返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript创建对象的几种方式及关于this指向问题
  • 169
分享到

JavaScript创建对象的几种方式及关于this指向问题

2024-04-02 19:04:59 169人浏览 薄情痞子
摘要

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

工厂模式的缺点:

  • 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()

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

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

--结束END--

本文标题: JavaScript创建对象的几种方式及关于this指向问题

本文链接: https://lsjlt.com/news/164912.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript创建对象的几种方式及关于this指向问题
    目录工厂模式构造函数模式关于 this原型模式工厂模式 工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。 function createPerson(...
    99+
    2024-04-02
  • 详解JavaScript原型对象的this指向问题
    目录一、this指向二、修改this指向1、call()方法2、apply()方法总结 一、this指向 构造函数中的this 指向实例对象。那么原型对象this的指向呢? 如下:...
    99+
    2024-04-02
  • javascript创建对象的几种常见方法
    本篇内容介绍了“javascript创建对象的几种常见方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!既...
    99+
    2024-04-02
  • java创建对象的方式有哪几种
    在Java中,可以通过以下几种方式创建对象:1. 使用new关键字:通过使用new关键字,可以调用类的构造方法实例化一个对象。例如:...
    99+
    2023-10-10
    java
  • javascript中有哪几种创建对象的方法
    本篇内容介绍了“javascript中有哪几种创建对象的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • .NET中创建对象的几种方式和对比
    目录使用标准反射的 Invoke 方法使用 Activator.CreateInstance 使用 Microsoft.Extensions.DependencyInjection ...
    99+
    2024-04-02
  • 关于JavaScript数组对象去重的几种方法
    数组对象如下: let repeatData = [ { id: 1, name: 'sun', age: 18 }, { id: 1, name: ...
    99+
    2023-05-17
    JavaScript数组去重 js数组对象去重
  • 关于Java创建线程的2种方式以及对比
    目录1. 继承Thread类2. 实现Runnable接口:创建线程的两种方式对比:线程的完整生命周期:总结Java中两种创建线程的方式: 1. 继承Thread类 重写run()方...
    99+
    2024-04-02
  • 基于SpringIOC创建对象的四种方式总结
    我们平时创建对象的方式无非就是以下两种: 有参构造 、无参构造 我们来看看在Spring中怎么处理这两种情况 首先我们先创建一个实体类: package com.MLXH.poj...
    99+
    2024-04-02
  • JavaScript创建对象的方法以及各种模式的实例介绍
    这篇文章主要介绍“JavaScript创建对象的方法以及各种模式的实例介绍”,在日常操作中,相信很多人在JavaScript创建对象的方法以及各种模式的实例介绍问题上存在疑惑,小编查阅了各式资料,整理出简单...
    99+
    2024-04-02
  • JavaScript中创建对象的三种方式分别是什么
    JavaScript中创建对象的三种方式分别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Javascript中的一切几乎都是对象,...
    99+
    2024-04-02
  • 关于Java中String创建的字符串对象内存分配测试问题
    一、创建String对象的两种常用方法比较 举例说明 String str1 = "Java天下第一"; //方法1 String str2 = new String("Java...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作