是什么取代了 JavaScript 中已弃用的__proto__
What has replaced the deprecated __proto__ in JavaScript
我正在尝试弄清楚如何在不使用 new 运算符的情况下从另一个实例化的对象实例化一个新对象。下面的代码有效,但我听说__proto__属性已贬值。
var MyObject = function( arg ) {
this.value = arg;
};
MyObject.prototype.getValue = function() {
return this.value;
};
// Standard way of instantiating an object
var object1 = new MyObject( 'foo' );
// Creating new object based on another without using new operator
var object2 = {};
object2.__proto__ = object1.__proto__
object1.constructor.call( object2, 'bar' );
console.log( object1 );
console.log( object2 );
那么如果没有__proto__属性,我将如何做到这一点呢?
自__proto__
的MDN文档,
__proto__
属性已弃用,不应使用。 应该使用Object.getPrototypeOf
而不是__proto__
getter来确定对象的[[原型]]。 强烈不鼓励改变对象的[[原型]],无论如何完成,因为它非常慢,并且不可避免地会减慢现代JavaScript实现中的后续执行速度。 但是,ES6 中提供了Object.setPrototypeOf
作为__proto__
二传手的非常偏爱的替代品。
但是您的实际代码有效,让我们看看为什么。
首先,任何使用 Object 文字创建的对象都将具有与
Object.prototype
相同的__proto__
属性。你可以像这样检查这个var object2 = {}; console.log(object2.__proto__ === Object.prototype); # true
由于
object1
是使用MyObject
函数创建的,因此以下情况是正确的console.log(object1.__proto__ === MyObject.prototype); # true
当你说
object2.__proto__ = object1.__proto__;
从 2 可以看出,它与,
object2.__proto__ = MyObject.prototype;
所以,你只是让 JavaScript 相信,
object2
也是MyObject
的对象。由于我们将
MyObject
的原型分配给object1
的原型,因此两个对象的constructor
是相同的console.log(object1.constructor === object2.constructor);
然后你调用
MyObject
函数,object2
作为this
。object1.constructor.call( object2, 'bar' );
由于不建议更改__proto__
,因此最好的方法是仅使用new
关键字
var object1 = new MyObject('foo'),
object2 = new MyObject('bar');
但是,假设你只有object1
,但没有MyObject
的定义。然后,您可以像这样使用 constructor
属性
object2 = new object1.constructor('bar');
正如thefoureye所提到的,在创建对象后更改对象的[[原型]]是非常不鼓励的。
但是,在您的用例中,您实际上没有理由在对象生命周期中的某个随机点更改 [[原型]],而是希望使用给定的 [[Prototype]] 创建一个对象。
实现此目的的方法Object.create
,它创建一个具有指定 [[Prototype]] 值的对象:
var object2 = Object.create(object1);
object1.constructor.call(object2, 'bar');
如果你想要的环境不支持 Object.create,MDN 页面上有一个填充程序。虽然不完美(未涵盖所有功能),但填充程序正是在这种情况下所需的。
看起来 ECMAScript 6 的最新草案已经标准化__proto__
。见 https://people.mozilla.org/~jorendorff/es6-draft.html B.2.2.1节。
- 我如何用纯JavaScript取代jQuery的toggleClass方法
- 什么正在取代我的'以及“;javascript代码中使用'和&”;
- 如何将事件处理程序分配给proto.io开关
- html() 真的取代了 html 代码吗?
- JavaScript/PHP 刷新取代了 HTML 元素类
- 如何用新版本的因果报应取代被弃用的吞咽因果报应
- 取代了棱角分明的深度观察者
- 用Google Sheets完全取代MySQL(或任何SQL)数据库
- Regex取代“;t〃;用“;T”;只有在“;a”"o”"u〃;使用javascript
- 具有的协议缓冲区无法从.proto生成js
- Javascript - 用 Javascript 编写 HTML 代码的更简洁的方法(取代 jQuery)
- 为什么javascript不会取代innerHTML的屏幕分辨率检查
- 谷歌地图地标不会取代旧的地标
- 用其他地方的重定向取代 Javascript 重定向
- 为什么这个JavaScript不能取代工作?(不包含正则表达式)
- return !!( proto === null || proto.constructor === Object );
- 通过 $.ajax 获取数据,我怎样才能以“角度”的方式做到这一点.$http取代 $.ajax 吗?
- javascript:表单不仅被IE取代,而且,它适用于所有其他浏览器
- 任何其他取代可见性崩溃的解决方案
- 咖啡脚本多行正则表达式取代了混乱