当前位置 : 主页 > 网络编程 > JavaScript >

解读new Object()和Object.create()的区别

来源:互联网 收集:自由互联 发布时间:2023-03-22
目录 Object.create() new Object() 区别 创建对象new Object() 和 Object.create()区分 总结 Object.create() 创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 --MDN 语法 Object.create(proto, [
目录
  • Object.create()
  • new Object()
  • 区别
  • 创建对象new Object() 和 Object.create()区分
  • 总结

Object.create()

创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 --MDN

语法

Object.create(proto, [propertiesObject]);

参数

proto:传递一个现在有的对象,即新对象的原型对象(新创建的对象_proto_属性指向现有属性)。

第一个参数proto的值为null,那么创建出来的对象是一个{}(空对象)并且没有原型;

Objecr.create({name:'lili'});

Objecr.create(null);

propertiesObject:可选,给新对象添加新属性以及描述器。如果没有指定即创建一个{},有原型也有继承Object.prototype上的方法。。

返回值

一个新对象,带着指定的原型对象和属性

小试牛刀

//题目
var a = {num:2};
var b = Object.create(a);
//问题,以下顺序执行,值是?
b.num
b.num++ 
a.num 
1. b.num == 2
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
也就是b.__proto__ == a
所以虽然b是个空对象,但会从原型上一直找值。
b.num == b.__proto__.num == 2
2. b.num++ == 2
b.num为2,++运算符是先用后加,这时b.num++还是2
3. a.num == 2
b.num 在执行 ++ 操作之后,这时的b为{num:3},不影响a.

new Object()

new创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

  • 创建一个空的对象(即{})
  • 链接该对象(即设置该对象的构造函数)到另一个对象
  • 将步骤1新创建的对象作为this的上下文
  • 如果该函数没有返回对象,则返回this
  • new会创建一个新对象,并且这个新对象继承构造函数的prototype,也就是说创建的实例的proto指向构造函数的prototype
  • new Object()会创建一个实例,该实例的proto指向Object的prototype
new Object();

new Object({name:'lili'});

区别

new Object()继承内置对象Object,而Object.create()则是继承指定对象可以通过Object.create(null) 创建一个干净的对象,也就是没有原型,而 new Object()创建的对象是 Object的实例,原型永远指向Object.prototype 

创建对象new Object() 和 Object.create()区分

new Object() 和 Object.create() 创建对象有什么不同之处,先看一个例子:

  var foo = {
    something: function() {
        console.log( "Tell me something good..." );
    }
};
foo.c = 1
var a = Object.create( foo );
var b = new Object(foo)
foo.foo='foo'
a.a='a'
b.b = 'b'
b.something()
a.something(); // Tell me something good...
console.log('a:',a)
console.log('b:',b)
console.log('foo:',foo)

打印结果:

b.something(); //Tell me something good…
a.something(); // Tell me something good…
console.log(‘a:’,a) // a: {a: “a”}
console.log(‘b:’,b) //b: {c: 1, foo: “foo”, b: “b”, something: ƒ}
console.log(‘foo:’,foo) //foo: {c: 1, foo: “foo”, b: “b”, something: ƒ}

发现:

在控制台上打印,看出这两种创建对象区别,十分清晰,create创建的对象只是原型指向foo,之后它俩无任何关系了,无论foo怎么修改,都不会影响a,a添加属性也不会影响foo,new 方式则会相互影响扩展

当要设计通用组件或模块时,假设要调用 a.something(),如果 a中不存在 something()时这条语句也可以正常工作的话,那你的 API 设计就会变得很“神奇”,对于未来维护者来说这可能不太好理解。

但是你可以让你的 API 设计不那么“神奇”,同时仍然能发挥 [[Prototype]] 关联的威力:

var foo= {
	something: function() {
		console.log( "something!" );
	}
};
var a= Object.create(foo);
a.doSomething= function() {
	this.something(); // 内部委托!
};
a.doSomething(); // "something!"

这里我们调用的 a.doSomething() 是实际存在于 a中的,这可以让我们的 API 设计更加清晰(不那么“神奇”)。从内部来说,我们的实现遵循的是委托设计模式,通过 [[Prototype]] 委托到foo.something()。

小结一下吧:

Object.create(…) 会创建一个新对象(bar)并把它关联到我们指定的对象(foo),这样 我们就可以充分发挥 [[Prototype]] 机制的威力(委托)并且避免不必要的麻烦(比如使 用 new 的构造函数调用会生成 .prototype 和 .constructor 引用)。。create()则不会生成这些引用,避免一些不必要的麻烦

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。

上一篇:JavaScript中如何计算字符串文本的宽度
下一篇:没有了
网友评论