(1)需求最近在看八字类的文章,看到了原型链中看到的知识点。在开发过程中,可能会使用1-2种以上。没想到这么多。在MDN上,我发现有些地方和控制台打印的不一致。只是想自己记录一下,方便以后发现问题修复。(二)四种方法1.使用语法结构创建的对象varo={a:1};//o这个对象继承了Object.prototype上面的所有属性//o它没有一个名为hasOwnProperty的属性//hasOwnProperty它是Object.prototype的一个属性//所以o继承了Object.prototype的hasOwnProperty//Object.prototype的原型为null//原型链如下://o--->Object.prototype--->nullvara=["yo","whadup","?"];//数组都是继承自Array.prototype//(Array.prototype包含indexOf,forEach等方法)//原型链如下://a--->Array.prototype--->Object.prototype--->nullfunctionf(){return2;}//函数都是继承自Function.prototype//(Function.prototype包含call,bind等方法)//原型链如下://f--->Function.prototype--->Object.prototype--->null2.JavaScript中使用构造函数创建的对象,一个构造函数实际上是一个n普通功能。当使用new操作符作用于这个函数时,可以称之为构造函数(constructor)。函数图(){this.vertices=[];this.edges=[];}Graph.prototype={addVertex:function(v){this.vertices.push(v);}};varg=newGraph();console.log(g)//g是一个生成的对象,它自己的属性包括'vertices'和'edges'。//g.[[Prototype]]在实例化g时指向Graph.prototype。3.使用Object.create创建的对象ECMAScript5中引入了一个新方法:Object.create()。可以调用此方法来创建新对象。新对象的原型是调用create方法时传入的第一个参数:vara={a:1};//a--->Object.prototype--->nullvarb=Object.create(a);//b--->a--->Object.prototype--->nullconsole.log(b.a);//1(继承)varc=Object.create(b);//c--->b--->a--->Object.prototype--->nullvard=Object.create(null);//d--->nullconsole.log(d.hasOwnProperty);//未定义,因为d使用class关键字创建的对象没有继承自Object.prototype4ECMAScript6引入了一组新的关键字来实现类。使用基于类的语言的开发人员会发现这些结构很熟悉,但又有所不同。JavaScript仍然基于原型。这些新关键字包括class、constructor、static、extends和super。"usestrict";classPolygon{constructor(height,width){this.height=height;this.width=宽度;}}classSquareextendsPolygon{constructor(sideLength){super(sideLength,sideLength);}getarea(){返回this.height*this.width;}setsideLength(newLength){this.height=newLength;this.width=newLength;}}varsquare=newSquare(2);(3)创建对象的四大优点对比ConsNameExampleProsConsNew-initializationfunctionfoo(){}foo.prototype={foo_prop:"fooval"};函数bar(){}varproto=newfoo;proto.bar_prop="barval";bar.prototype=proto;varinst=新柱;控制台日志(inst.foo_prop);控制台日志(inst.bar_prop);复制到剪贴板支持当前和所有可以想象的浏览器(IE5.5有效)。这种方法速度非常快,非常符合标准,并且充分利用了JIT优化。为了使用此方法,必须初始化相关函数。在初始化期间,构造函数可以存储每个对象必须生成的唯一信息。然而,这种独特的信息只生成一次,这可能会带来潜在的问题。此外,构造函数的初始化可能会在对象上放置不需要的方法。但是,如果你只是在自己的代码中使用它,并且知道(或者通过注释等方式写过)每段代码在做什么,这些一般都不是问题(事实上,往往是有益的)。Object.createfunctionfoo(){}foo.prototype={foo_prop:"fooval"};函数bar(){}varproto=Object.create(foo.prototype);proto.bar_prop="barval";酒吧.原型=原型;varinst=新柱;控制台日志(inst.foo_prop);控制台日志(inst.bar_prop);复制到剪贴板functionfoo(){}foo.prototype={foo_prop:"fooval"};functionbar(){}varproto=Object.create(foo.prototype,{bar_prop:{value:"barval"}});bar.prototype=proto;varinst=新柱;console.log(inst.foo_prop);console.log(inst.bar_prop)CopytoClipboard支持当前所有非微软版本或IE9以上浏览器。允许一次性直接设置__proto__属性,以便浏览器更好地优化对象。它还允许通过Object.create(null)创建一个没有原型的对象。不支持IE8以下版本。不过,随着微软不再为系统上运行的旧版本浏览器提供支持,这在大多数应用程序中不会成为主要问题。此外,这种缓慢的对象初始化在使用第二个参数时有可能成为性能黑洞,因为每个对象的描述符属性都有自己的描述对象。在处理成百上千个对象格式的对象描述时,会导致严重的性能问题。Object.setPrototypeOffunctionfoo(){}foo.prototype={foo_prop:"fooval"};函数bar(){}varproto={bar_prop:"barval"};Object.setPrototypeOf(proto,foo.prototype);bar.prototype=proto;varinst=新柱;控制台日志(inst.foo_prop);控制台日志(inst.bar_prop);复制到剪贴板functionfoo(){}foo.prototype={foo_prop:"fooval"};函数栏(){}varproto;proto=Object.setPrototypeOf({bar_prop:"barval"},foo.prototype);bar.prototype=proto;varinst=新柱;console.log(inst.foo_prop);console.log(inst.bar_prop)复制到剪贴板支持所有现代浏览器和MicrosoftIE9+浏览器。允许动态操作对象的原型,甚至可以强制将原型添加到使用Object.create(null)创建的没有原型的对象。此方法性能不佳,应弃用。如果你在生产中使用这个方法,是不可能快速运行Javascript的,因为很多浏览器会优化原型,在调用实例之前试图猜测方法在内存中的位置,但是动态设置原型会干扰所有的优化,它可能甚至导致浏览器使用完全未优化的代码重新编译才能成功运行。不支持IE8及以下浏览器版本。原型函数foo(){}foo.prototype={foo_prop:"fooval"};函数bar(){}varproto={bar_prop:"barval",__proto__:foo.prototype};bar.prototype=proto;varinst=新柱;控制台日志(inst.foo_prop);控制台日志(inst.bar_prop);复制到剪贴板控制台日志(inst.foo_prop);console.log(inst.bar_prop)复制到剪贴板支持所有现代非Microsoft版本和IE11+浏览器。将__proto__设置为非对象值会静默失败而不会引发错误。它应该被完全丢弃,因为这种行为完全是非性能的。如果你在生产中使用这个方法,是不可能快速运行Javascript的,因为很多浏览器会优化原型,在调用实例之前试图猜测方法在内存中的位置,但是动态设置原型会干扰所有的优化,它可能甚至导致浏览器使用完全未优化的代码重新编译才能成功运行。不支持IE10及以下浏览器版本。以上参考链接https://developer.mozilla.org...
