1、原型对象(原型)、原型链
先放一张在网上看到的关于原型和原型链的图,非常不错。
如果你能看懂,那就对原型链有了一定了解,如果看不懂,对照下面这几点来看图:
js中所有函数都有一个prototype属性,这个属性引用了一个对象(fun.prototype),即原型对象,也简称为原型(下面都称原型)
所有原型都有constructor属性和__proto__属性
constructor属性指向构造函数(方法)
__proto__属性指向自己的继承父类 (即它的构造函数的
原型)
第四点得到的结果,又回到了第二点,这样就构成了原型链。
js中一切皆对象,而对象都有一个__proto__属性,这也解释了原型为什么有这个属性。
Object.prototype的_proto_指向null(最顶级的原型对象),所有原型链的最顶层都是Object.prototype
补充:
instanceof 运算符:A instanceof B 检查 A的原型链上是否存在B.prototype。
console.log([1,2,3] instanceof Array); // true
console.log([1,2,3] instanceof Object); // true
Function是最顶层的构造方法,所有对象都由Function方法构造,包括Object方法,Function方法。
console.log(Object instanceof Function); //true
console.log(Function instanceof Function); //true
(上图可以看出三个函数对象的__proto__都指向了Function.prototype)
Object对象和Function方法是相互依赖的
alert(Function instanceof Object); // true
和2对比,可以看出。
原型链只有在检索值的时候才会用到,如果我们尝试去获取对象的某个属性值,但该对象没有此属性值,那么js就会在其原型对象中找,如果还没有,那么再从它的原型中找,直到Object.prototype,如果该对象原型链中也没有找到,则返回undefined。
Object.create方法
内部原理:
if(typeof Object.beget !== 'function') {
Object.create = function(o) {
var F = function () {};
F.prototype = o;
return new F();
}
}
这个方法创建一个使用原对象作为其原型的新对象。
var obj = {
'a': 'a',
'b': 'b'
}
var obj1 = Object.create(obj);
obj1.__proto__.c = 'c';
console.log(obj);// {a:'a',b:'b',c:'c'} 可以看出obj1使用obj作为其构造函数原型
用途:在工厂函数中,将相同的属性和方法放在构造函数的原型链中,不同的放在构造函数中。
2、构造函数
function Foo() {}
var foo = new Foo();
1、构造函数也是函数,未了区分,构造函数的函数名首字母大写。(不是必须,但最好)
2、new的内部实现原理:(建议理解原型和原型链,在返回来看这个)
var foo = {};
foo.__proto__ = Foo.prototype;
Foo.call(foo);
通过上面的代码可以看出:通过实例化构造函数,所生成的对象,它的继承父类(foo.__proto__)就是构造函数的原型(Foo.prototype)。
function Foo () {
this.a = 'a';
this.b = 'b';
}
var obj1 = new Foo();
var obj2 = {
a: 'a',
b: 'b'
}
console.log(‘obj1的构造函数是: ’ + obj1.__proto__.constructor);
// obj1的构造函数是: function Foo () { this.a = 'a'; this.b = 'b';}
console.log(‘obj2的构造函数是: ’ + obj2.__proto__.constructor);
// obj2的构造函数是: function Object() { [native code] }