美文网首页
JS中4 个用于拓展原型链的方法比较

JS中4 个用于拓展原型链的方法比较

作者: 99ZY | 来源:发表于2021-11-29 23:13 被阅读0次

**设置**对象的属性,如果在对象中找不到,会去原型链上去找!

总结:4 个用于拓展原型链的方法

下面列举四种用于拓展原型链的方法,以及他们的优势和缺陷。下列四个例子都创建了完全相同的 inst 对象(所以在控制台上的输出也是一致的),为了举例,唯一的区别是他们的创建方法不同。

1、New-initialization 初始化

function foo(){}
foo.prototype = {
  foo_prop: "foo val"
};
function bar(){}
var proto = new foo;
proto.bar_prop = "bar val";
bar.prototype = proto;
var inst = new bar;
console.log(inst.foo_prop);
console.log(inst.bar_prop);

优缺点:
| 支持目前以及所有可想象到的浏览器(IE5.5都可以使用)。 这种方法非常快,非常符合标准,并且充分利用JIT优化。 | 为使用此方法,必须对相关函数初始化。 在初始化过程中,构造函数可以存储每个对象必须生成的唯一信息。但是,这种唯一信息只生成一次,可能会带来潜在的问题。此外,构造函数的初始化,可能会将不需要的方法放在对象上。然而,如果你只在自己的代码中使用,你也清楚(或有通过注释等写明)各段代码在做什么,这些在大体上都不是问题(事实上,通常是有益处的)。 |

2、Object.create

function foo(){}
foo.prototype = {
  foo_prop: "foo val"
};
function bar(){}
var proto = Object.create(
  foo.prototype
);
proto.bar_prop = "bar val";
bar.prototype = proto;
var inst = new bar;
console.log(inst.foo_prop);
console.log(inst.bar_prop);

function foo(){}
foo.prototype = {
  foo_prop: "foo val"
};
function bar(){}
var proto = Object.create(
  foo.prototype,
  {
    bar_prop: {
      value: "bar val"
    }
  }
);
bar.prototype = proto;
var inst = new bar;
console.log(inst.foo_prop);
console.log(inst.bar_prop)

优缺点

| 支持当前所有非微软版本或者 IE9 以上版本的浏览器。允许一次性地直接设置 __proto__ 属性,以便浏览器能更好地优化对象。同时允许通过 Object.create(null)来创建一个没有原型的对象。 | 不支持 IE8 以下的版本。然而,随着微软不再对系统中运行的旧版本浏览器提供支持,这将不是在大多数应用中的主要问题。 另外,这个慢对象初始化在使用第二个参数的时候有可能成为一个性能黑洞,因为每个对象的描述符属性都有自己的描述对象。当以对象的格式处理成百上千的对象描述的时候,可能会造成严重的性能问题。

3、Object.setPrototypeOf

function foo(){}
foo.prototype = {
  foo_prop: "foo val"
};
function bar(){}
var proto = {
  bar_prop: "bar val"
};
Object.setPrototypeOf(
  proto, foo.prototype
);
bar.prototype = proto;
var inst = new bar;
console.log(inst.foo_prop);
console.log(inst.bar_prop);

function foo(){}
foo.prototype = {
  foo_prop: "foo val"
};
function bar(){}
var proto;
proto=Object.setPrototypeOf(
  { bar_prop: "bar val" },
  foo.prototype
);
bar.prototype = proto;
var inst = new bar;
console.log(inst.foo_prop);
console.log(inst.bar_prop)

优缺点

 支持所有现代浏览器和微软IE9+浏览器。允许动态操作对象的原型,甚至能强制给通过 `Object.create(null) `创建出来的没有原型的对象添加一个原型。 | 这个方式表现并不好,应该被弃用。如果你在生产环境中使用这个方法,那么快速运行 Javascript 就是不可能的,因为许多浏览器优化了原型,尝试在调用实例之前猜测方法在内存中的位置,但是动态设置原型干扰了所有的优化,甚至可能使浏览器为了运行成功,使用完全未经优化的代码进行重编译。 不支持 IE8 及以下的浏览器版本。 |

4、__proto__

function foo(){}
foo.prototype = {
  foo_prop: "foo val"
};
function bar(){}
var proto = {
  bar_prop: "bar val",
  __proto__: foo.prototype
};
bar.prototype = proto;
var inst = new bar;
console.log(inst.foo_prop);
console.log(inst.bar_prop);

var inst = {
  __proto__: {
    bar_prop: "bar val",
    __proto__: {
      foo_prop: "foo val",
      __proto__: Object.prototype
    }
  }
};
console.log(inst.foo_prop);
console.log(inst.bar_prop)

优缺点

  支持所有现代非微软版本以及 IE11 以上版本的浏览器。将 `__proto__` 设置为非对象的值会静默失败,并不会抛出错误。 | 应该完全将其抛弃因为这个行为完全不具备性能可言。 如果你在生产环境中使用这个方法,那么快速运行 Javascript 就是不可能的,因为许多浏览器优化了原型,尝试在调用实例之前猜测方法在内存中的位置,但是动态设置原型干扰了所有的优化,甚至可能使浏览器为了运行成功,使用完全未经优化的代码进行重编译。不支持 IE10 及以下的浏览器版本。

相关文章

  • JS中4 个用于拓展原型链的方法比较

    **设置**对象的属性,如果在对象中找不到,会去原型链上去找! 总结:4 个用于拓展原型链的方法[https://...

  • 2019-08-05 拓展现有函数

    定义、声明的函数 拓展原型链上的方法

  • 浅析JS继承方法

    JS 实现继承的方法有:1.原型链继承2.构造函数继承3.组合继承(原型链继承 + 构造函数继承)4.原型式继承(...

  • 谈谈 js 原型链

    原型链是为了实现继承,也就是说js的继承是基于原型链的。原型-prototype,是一个对象,用于存放共享的属性和...

  • javascript的原型链解读

    关于原型链的调用原理 只要明白js里访问一个对象的方法或属性的过程,就能彻底搞明白js的原型链。(首先要明确,js...

  • JS闭包问题(一)

    之前我写过一篇JavaScript原型与原型链的文章,此属于JS中的重难点。 而闭包,是JS中除了原型链之外又一个...

  • 原型链以及继承

    原型链 原型链类似关系链,几乎所有的js对象都会有通过原型链prototype继承过来的方法或者属性,在java和...

  • 在nodejs中面向对象:Bearcat

    JS中的面向对象 最最最开始,我们先来说说JS中的面向对象。 原型链 参考文章:图解Javascript原型链 J...

  • 2-9原型和原型链 - instanceof

    2-9原型和原型链 - instanceof 用于判断引用类型数学哪个构造函数的方法 toSting在f中找,没有...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

网友评论

      本文标题:JS中4 个用于拓展原型链的方法比较

      本文链接:https://www.haomeiwen.com/subject/hujrxrtx.html