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
深入了解instanceof : JavaScript instanceof 运算符深入剖析
- 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。
- instanceof 运算符:A instanceof B 检查 A的原型链上是否存在B.prototype。
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] }