Prototype is a property belonging only to functions. Used in case the function happens to be used as a constructor. You assign properties to a constructor's prototype if you would like them to be inherited by its instances; rather than directly assigned, which saves memory.
// 这个是组合继承(原型链+构造函数)
function Foo(bar) {
this.bar = bar
}
Foo.prototype.showBar = function() {
console.log(this.bar)
}
// var f = new Foo(222)
// f.showBar() // 222
// new 约等价于
var f = {}
f.__proto__ = Foo.prototype
Foo.call(f, 22)
f.showBar() // 22
apply/call就第二个参数的不同。apply的实现:
Function.prototype.apply = function(obj, arr) {
obj = obj || window;
obj._tem = this;
var result;
if (!arr) {
result = obj._tem();
} else {
var args = [];
for (var i = 0, len = arr.length; i < len; i ++) {
args.push('arr[' + i + ']');
}
result = eval('obj._tem(' + args + ')')
}
delete obj._tem;
return result;
}
原型链:__proto__
每个对象都内置proto属性,是用来寻找原型链的。
Function instanceof Object // true`
函数也是Object,所以
function Foo() {}
Foo.__proto__.constructor === Function // true
var f = new Foo()
f.__proto__ === Foo.prototype // true, f的__proto指向Foo的原型对象
f.__proto__.constructor === Foo // true
Foo.prototype.constructor === Foo // true,Foo的原型对象的构造器是Foo
理解了以上的,再来想一下原型链。当你调用对象a的方法时,若没有在a中找到,则去a的proto对象(也就是a的构造器A的prototype)中寻找,a ---> A ---> 逐级寻找 --->Object.prototype,最后是Object构造函数的原型对象。
接下来是继承:
function Foo() {}
function Bar() {}
Bar.prototype = new Foo()
Bar.prototype.constructor = Bar
这样,Bar的prototype指向的对象里
- constructor: Bar
- __proto__: Foo (是new Foo()出来的一个实例,相当于把Bar.prototype.__proto__ = Foo.prototype,然后执行Foo.call(Bar))
JS中,prototype是函数的属性。被用于函数作为构造器的场景。当你想让构造器的properties都被它的实例继承,应该把这些properties赋予构造器的prototype,而不是直接assign,可以节约一点内存。
先实现类:
apply/call就第二个参数的不同。apply的实现:
原型链:
__proto__
每个对象都内置proto属性,是用来寻找原型链的。函数也是Object,所以
理解了以上的,再来想一下原型链。当你调用对象a的方法时,若没有在a中找到,则去a的proto对象(也就是a的构造器A的prototype)中寻找,
a ---> A ---> 逐级寻找 --->Object.prototype
,最后是Object构造函数的原型对象。接下来是继承:
这样,Bar的prototype指向的对象里
利用prototype实现了继承~~~
最后的总(tu)结(cao)
ES2015中有了class、extends关键字,写个类终于不用这么麻烦了。但是为什么面试的时候,还要问这些JS的糟粕呢???