欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript进阶之原型链

程序员文章站 2022-03-12 18:10:17
对象 JavaScript中将对象分为普通对象和函数对象。 使用函数对象可以创建普通对象,普通对象没法创建函数对象。 凡是通过new Function创建的对象都是函数对象,其他都是普通对象(通常通过Object创建),可以通过typeof来判断。 原型对象(prototype) Prototype ......

对象

 1 function f1(){
 2 };
 3 typeof f1 //"function"函数对象
 4 
 5 
 6 var o1 = new f1();
 7 typeof o1 //"object"普通对象
 8 
 9 var o2 = {};
10 typeof o2 //"object"普通对象

javascript中将对象分为普通对象函数对象

使用函数对象可以创建普通对象,普通对象没法创建函数对象。

凡是通过new function创建的对象都是函数对象,其他都是普通对象(通常通过object创建),可以通过typeof来判断。

原型对象(prototype

prototype

prototype有原型、蓝本的意思,只有函数对象才会有原型(prototype)。

所谓原型,就是函数用来创建实例(普通)对象的蓝本(原型)。

每个原型都有一个 constructor 属性指向关联的构造函数。

__proto__

每一个javascript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型(prototype)。

constructor

构造函数,即用来创建实例的函数,即关联的函数对象本身。

验证

在火狐或者谷歌浏览器控制台中新建一个普通对象,查看他的属性。

1 var o = {};
2 console.log(o.prototype); //undefined  普通对象没有prototype属性
3 console.log(o instanceof object); //true  o是object的实例
4 console.log(o.__proto__ === object.prototype) //true  o的__proto__指向object的prototype
5 console.log(object === object.prototype.constructor) //true  object.prototype.constructor指向object本身
6 console.log(object.prototype.constructor) //function object() 函数对象原型的构造函数指向这个函数 
7 console.log(object.prototype.__proto__); //null object.prototype的__proto__为null,为原型链终点

新建一个函数对象,查看他的属性。

1 function demo() { };
2 var f1 = new demo();
3 console.log(f1.prototype); //undefined  通过函数对象穿创建的是普通对象,demo本身是函数对象
4 console.log(f1 instanceof demo); //true  f1是demo的实例
5 console.log(f1.__proto__ === demo.prototype); //true
6 console.log(demo === demo.prototype.constructor);//true
7 console.log(demo.prototype.__proto__ === object.prototype);//true  demo原型的__proto__指向object的原型prototype
8 console.log(object.prototype.__proto__); //null

原型的重要功能就是用作继承。

原型链(prototype chain

javascript中,每个对象都会在内部生成一个__proto__ 属性,当我们访问一个对象属性时,如果这个对象不存在就回去__proto__ 指向的对象里面找,一层一层找下去,这就是javascript原型链的概念。

提升:

  1. 在原型链上查找属性比较耗时,对性能有副作用,这在性能要求苛刻的情况下很重要。另外,试图访问不存在的属性时会遍历整个原型链。
  2. 遍历对象的属性时,原型链上的每个可枚举属性都会被枚举出来。要检查对象是否具有自己定义的属性,而不是其原型链上的某个属性,则必须使用对象从object.prototype继承的 hasownproperty 方法。(使用 for in 遍历对象时推荐总是使用 hasownproperty 方法)

继承

javascript 并没有其他基于类的语言所定义的“方法”。在 javascript 里,任何函数都可以添加到对象上作为对象的属性。函数的继承与其他的属性继承没有差别。

继承意味着复制操作,在java和c#中,继承是完全复制生成新的对象。然而 javascript 默认并不会复制对象的属性,相反,javascript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。

结论

在编写使用它的复杂代码之前,理解原型继承模型是至关重要的。此外,请注意代码中原型链的长度,并在必要时将其分解,以避免可能的性能问题。此外,原生原型不应该被扩展,除非它是为了与新的javascript特性兼容。

参考文档: https://www.jb51.net/article/123976.htm

      https://github.com/mqyqingfeng/blog/issues/2

      https://developer.mozilla.org/zh-cn/docs/web/javascript/inheritance_and_the_prototype_chain