如何在js中创建对象,一直是一个值得关注的问题。有很多人在博客上进行了总结,但由于没有权威的定义,导致某些方式有多种不同的命名以及不同的变体。下文将介绍我总结的5种方式,如果没有遗漏的话,其他一些本文没有提及的创建方式应该都是下面5种方式的别名或者变体。欢迎各位读者在评论区补充我没有总结到的基本方式
1.直接字面量
let person={
key:value,
......
}
2.构造函数法
function Person(value){
this.key=value;//this作用域:当前对象
......
}
let wopelo=new Person("博主");
3.原型方式
function Person(){}
Person.prototype.key=value;
......
let wopelo=new Person();
4.混合方式(构造函数与原型方式组合)
function Person(value){
this.key=value;
......
}
Person.prototype={
key:value
......
}
let wopelo=new Person("博主");
5.工厂方式
function Person(value){
let o=new Object();
o.key=value;
......
return o;
}
//注意,有没有new依然可以返回正确的实例
let wopelo=Person("wopelo");
这种方式很好理解其工作原理,即在函数内部new一个object,然后在这个object上添加属性,最后将这个object返回。
值得注意的是,在示例中,最后生成实例时,没有用new,其实在这种方式中,实例化的时候用不用new无关紧要,因为根据new操作符的处理规则,当构造函数返回值为原始类型(包括没有return语句,此时返回undefined依然是原始类型),new+构造函数返回该构造函数的实例对象;如果构造函数返回值为对象,new+构造函数与直接执行该构造函数结果相同,均返回原本要return的对象
6.Object.create
语法
Object.create(proto,propertiesObject)
prop:必选,表示新创建对象的原型对象,如果proto参数不是 null 或一个对象,则抛出一个 TypeError 异常
propertiesObject:可选,一个对象,表示对对象属性的描述,包括数据描述符(configurable、enumerable、value、writable)和存取描述符(getter、setter)
实例
let o=Object.create(Object.prototype,{
foo: {
writable:true,
configurable:true,
value: "hello"
},
bar: {
configurable: false,
get: function() { return 10 },
set: function(value) {
console.log("Setting `o.bar` to", value);
}
},
char:{
value:function(){
console.log("char");
}
}
});
执行上述代码,得到结果
继承
现在,可以试着用Object.creat实现继承,现在已经有了一个用Object.creat创建的实例 o
let y=Object.create(o)
//注意,第一个参数是o而不是o.__proto__
现在,Object.create()里面第一个参数是一个实例,如果是一个构造函数应该怎么办
function student(value){
this.key=value;
this.what="nani"
}
student.prototype.move="xxx";
let q=Object.create(student.prototype)
定义在实例上的属性(即定义在构造函数this上的属性)不会被Object.create继承,而定义在构造函数原型上的属性则会被继承