5 个回答

在prototype上添加方法是为了继承方便。你的写法没法将test.func继承给子类。而如果这样写:
let test = function() {

this.func = function(){}

}
和你的代码等价了,子类也可以继承func方法,如:
let subTest = function() {

test.call(this);

}
但是这里subTest.func 和 test.func虽然代码完全一致但却是两个不同变量,也就是说js编译后其实将相同代码又复制了一遍;想象一下如果有很多subTest实例,那么func函数就会被复制很多遍造成内存的浪费。而如果func是定义在test的prototype上时:
let test = function() {};
test.prototype.func = function(){};
let subTest = function() {

test.call(this);

}
subTest.prototype = new test();
这样形成了原型链,subTest上其实并没有func,但是调用subTest.func()时会沿着原型链向上查找到test.prototype.func。也就是说subTest可以试用func函数,同时又不会再创建一个新的func实例,这样节省了内存开销。

其实js还有很多种继承的实现方式,我这里解释的不是很清楚,如果要更详细的了解可以去看看《js高级程序设计》第6章的内容

直接添加也可,添加在原型上也可,添加在原型上的方法可以被继承并可以被其他对象引用

如果你此函数是一个构造函数,比如

function animal() {}
let dog = new animal()
dog.move = function () {
  console.log('move')
}

这样添加方法后,只有在dog这个实例里面才能访问到move函数
但是你想每个动物都有这个move函数

直接添加到animal()会在初始化实例的时候初始化此move函数,不符合高效的标准
所以都会添加到原型上

在prototype上的方法只会初始化一次,可以提供给所有实例使用,符合节省内存开销的标准
所以一般都会添加到原型对象

新手上路,请多包涵

楼主 我私信你了 看看消息啊

像你上面这种情况,test就是一个普通对象,它压根就没有原型:

let Person = {}
Person.age = 29

console.log(Person.prototype) // undefined

你将方法挂在test对象上,那就它就作为test对象的一个普通属性(方法)。
有些场景,你看到的将方法添加到其原型对象上,是为了继承,比如下面的例子:

function Person(name) {
  this.name = name;
}
Person.prototype.sayName = function () {
  console.log(this.name);
};

let foo = new Person('foo');
let bar= new Person('bar');
foo.sayAge = function () {
  console.log(20);
}

foo.sayName(); // foo
foo.sayAge(); // 20
bar.sayName(); // bar
bar.sayAge(); // 报错

上面代码中,Person是一个构造函数,通过在它的prototype上添加一个sayName方法,那么,所有通过Person构造函数产生的对象都会拥有sayName方法(共有)。如果直接添加,比如foo对象上的sayName方法,它只是foo对象才有的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏