JavaScript中创建对象有哪些方法,以及这些方法中this指向是如何变化的?

2026-04-03 07:141阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1637个文字,预计阅读时间需要7分钟。

JavaScript中创建对象有哪些方法,以及这些方法中this指向是如何变化的?

目录 + 工厂模式 + 构造函数模式 + 关于this + 原型模式 + 工厂模式 + 工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。+ function createPerson(name, age) { + let o={}; + o.name=name; + ... + }

目录
  • 工厂模式
  • 构造函数模式
    • 关于this
  • 原型模式

    工厂模式

    工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。

    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中,可以用不同的参数多次调用工厂函数,每次都会返回包含特定参数和一个方法的对象。可以解决创建多个类似对象的问题。

    工厂模式的缺点:

    • 1. 没有解决对象标识问题。
    • 2. 每次创建对象,都会创建一个公共的方法,而方法也是对象,所以造成内存浪费。

    构造函数模式

    在 JS 中, 构造函数是用于创建特定类型对象的。像ObjectArray这样的原生构造对象,运行时,可以直接在执行环境中运行。当然也可以自定义构造函数,以函数的形式为自己的对象类型定义属性和方法。

    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被赋值为这个新的对象(给新对象添加新的属性)
    • 执行构造函数中的代码,并且判断有无对象返回值,如果存在,则返回这个返回值,否则返回这个新的对象
    • 构造函数的优缺点: 首先,构造函数解决了对象的标识问题,但是如果构造函数中存在着函数,那么每次创建一个实例,就相当于函数也被重新创造了一遍,因为在JS中函数也是相当于对象,造成了对空间的浪费。

    关于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()

    通过上面创建的p1p2,共用了Student原型上的属性,相当于创造了两个拥有相同属性的不同对象。同理,如果上面的study改为了箭头函数,大家应该也能知道this绑定的是谁了吧。(Tip: new 和 显示绑定不可以同时使用)

    原型模式的优缺点 : 首先原型模式解决了上两种模式造成的空间浪费问题,但是,其属性都是共享的,所以一般来说,原型模式不会单独去使用。

    JavaScript中创建对象有哪些方法,以及这些方法中this指向是如何变化的?

    本文共计1637个文字,预计阅读时间需要7分钟。

    JavaScript中创建对象有哪些方法,以及这些方法中this指向是如何变化的?

    目录 + 工厂模式 + 构造函数模式 + 关于this + 原型模式 + 工厂模式 + 工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。+ function createPerson(name, age) { + let o={}; + o.name=name; + ... + }

    目录
    • 工厂模式
    • 构造函数模式
      • 关于this
    • 原型模式

      工厂模式

      工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。

      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中,可以用不同的参数多次调用工厂函数,每次都会返回包含特定参数和一个方法的对象。可以解决创建多个类似对象的问题。

      工厂模式的缺点:

      • 1. 没有解决对象标识问题。
      • 2. 每次创建对象,都会创建一个公共的方法,而方法也是对象,所以造成内存浪费。

      构造函数模式

      在 JS 中, 构造函数是用于创建特定类型对象的。像ObjectArray这样的原生构造对象,运行时,可以直接在执行环境中运行。当然也可以自定义构造函数,以函数的形式为自己的对象类型定义属性和方法。

      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被赋值为这个新的对象(给新对象添加新的属性)
      • 执行构造函数中的代码,并且判断有无对象返回值,如果存在,则返回这个返回值,否则返回这个新的对象
      • 构造函数的优缺点: 首先,构造函数解决了对象的标识问题,但是如果构造函数中存在着函数,那么每次创建一个实例,就相当于函数也被重新创造了一遍,因为在JS中函数也是相当于对象,造成了对空间的浪费。

      关于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()

      通过上面创建的p1p2,共用了Student原型上的属性,相当于创造了两个拥有相同属性的不同对象。同理,如果上面的study改为了箭头函数,大家应该也能知道this绑定的是谁了吧。(Tip: new 和 显示绑定不可以同时使用)

      原型模式的优缺点 : 首先原型模式解决了上两种模式造成的空间浪费问题,但是,其属性都是共享的,所以一般来说,原型模式不会单独去使用。

      JavaScript中创建对象有哪些方法,以及这些方法中this指向是如何变化的?