目录工厂模式构造函数模式关于 this原型模式工厂模式 工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。 function createPerson(
工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。
function createPerson(name, age) {
let o = {};
o.name = name;
0.age = age;
o.study = function() {
console.log(`${this.name} is studying`)
}
return o
}
const p1 = createPerson('张三', 18)
const p2 = createPerson('李四', 20)
p1.study() // 张三 is studying
值得一提的是,如果在 createPerson
函数中,o.study
改为箭头函数,那么打印的 this 会发生改变,这是因为箭头函数发生了 this
指向的问题。
工厂模式的优点: 在 createPerson
中,可以用不同的参数多次调用工厂函数,每次都会返回包含特定参数和一个方法的对象。可以解决创建多个类似对象的问题。
工厂模式的缺点:
在 js 中, 构造函数是用于创建特定类型对象的。像 Object
、Array
这样的原生构造对象,运行时,可以直接在执行环境中运行。当然也可以自定义构造函数,以函数的形式为自己的对象类型定义属性和方法。
function Student(name, age) {
this.name = name;
this.age = age;
this.study = function() {
console.log(`${this.name} is studying`)
}
}
const p1 = new Student('张三', 18)
const p2 = new Student('李四', 20)
通过上面的代码,可以实现和工厂模式一样的效果。但是值得注意的是: 如果这里的 study
函数变为箭头函数, this
的指向是不会发生变化的。
如同上面的代码,如果调用构造函数,就必须使用 new
关键字,在这个过程中,构造函数会做四件事情:
__proto__
赋值为该构造函数的显示原型 prototype
this
被赋值为这个新的对象(给新对象添加新的属性)在标准函数中, this 引用的是把函数当成方法调用的上下文对象,这个时候常称其为 this。
我们在上文说过,工厂模式和构造函数模式,其内部如果出现箭头函数,那么 this
的指向会出现不同,这是因为,箭头函数中不存在 this
, 箭头函数中的 this
, 会保留定义该函数的上下文,this
到底引用哪个对象必须到函数调用时,才会确定, 在工厂模式时, 虽然通过p1.study()
,进行调用,但是由于箭头函数内部没有 this
,所以向上查找,找到function createPerson
函数, 绑定 window
, 而在构造函数模式中this 赋值给了这个新的对象,相当于箭头函数的this
, 就是这个新的对象,也就是之后的实例。
可能,通过上面的描述,很多同学仍然对下面箭头函数中的this,会保留定义该函数的上下文不太理解,我列举一个例子。
// 工厂模式
function createPerson(name, age) {
let o = {};
o.name = name;
o.age = age;
o.study = () => {
console.log(`${this.name} is studying`)
}
return o
}
const obj = {
name: '张三'
}
const p1 = createPerson.call(obj, '李四', 20) // createPerson 绑定 obj, 那么箭头函数也会绑定 obj
p1.study() // 所以这里的输出是 张三 is studying,而不是 undefined
每个函数都会创建一个
prototype
属性,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。实际上,这个对象就是通过调用构造函数创建的对象的原型。使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。原来在构造函数中直接赋值给对象实例的值,可以直接赋值给他们的原型。
function Student() {}
Student.prototype.name = '张三';
Student.prototype.age = 20;
Student.prototype.friends = ['ls', 'ww'];
Student.prototype.study = function() {
console.log(`${this.name} is studying`)
}
const p1 = new Student()
const p2 = new Student()
通过上面创建的p1
, p2
,共用了Student
原型上的属性,相当于创造了两个拥有相同属性的不同对象。同理,如果上面的 study
改为了箭头函数,大家应该也能知道 this
绑定的是谁了吧。(Tip: new 和 显示绑定不可以同时使用)
原型模式的优缺点 : 首先原型模式解决了上两种模式造成的空间浪费问题,但是,其属性都是共享的,所以一般来说,原型模式不会单独去使用。
--结束END--
本文标题: JavaScript创建对象的几种方式及关于this指向问题
本文链接: https://lsjlt.com/news/164912.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0