当前位置: 首页 > news >正文

js创建对象

前言:

你可能会说,js创建对象谁不会啊,不是有手就行!但是你了解每种创建对象的方式有什么不同吗?他们有没有优劣之分?在es6推出class之前,又有哪些创建对象的方式,经历了哪些发展呢?

【普通字面量模式】

let person1 ={
    name:'zhangsan',
    age:18,
    sayName(){
        console.log(this.name)
    }
}

let person2 ={
    name:'lisi',
    age:19,
    sayName(){
        console.log(this.name)
    }
}

这种模式,别的缺点先不提,显著的劣势就是代码冗余严重,每创建一个对象就要将相同代码重写一遍。

【工厂函数模式】

function createPerson(name,age){
    return {
        name,
        age,
        sayName(){
            console.log(this.name)
        }
}

let person1=createPerson('zhangsan',18)
let person2=createPerson('lisi',19)

解决了代码冗余问题,通过传参创建不同的对象。这种模式最大的缺点是什么呢?就是创建出来的对象没有类型标识。

【构造函数模式】

function Person(name,age){
  this.name=name;
  this.age=age;
  this.sayName=function(){
    console.log(this.name)
  }
}
let person1=new Person('zhangsan',18)
let person2=new Person('lisi',19)

这样,解决了工厂函数模式创建对象没有类型标识的问题。

通过new 关键字,调用构造函数,发生了哪些事情呢?

1、首先,会创建一个空对象{}

2、让这个空对象的__proto__指向Person.prototype

3、让this指向这个空对象

4、执行构造函数内部的代码,给空对象添加相应的属性和方法

5、如果构造函数返回了引用类型的值,则将该引用类型值返回,否则,将前面初始化的对象返回

注意问题:

构造函数也是函数,他和普通函数本质上是一样的,只是通过new关键字调用,他便被赋予了构造函数的意义。假如上面的Person函数没有通过new关键字调用会怎么样呢?答案是添加的属性和方法会被挂在全局对象window上,因为函数内部的this指向window对象。因此,构造函数首字母一般大写(虽然也没啥用),用以区分普通函数和构造函数。到了es6,出现了箭头函数,就是用以解决函数的二义性问题,因为他不能用new关键字调用,就不能作为构造函数。

构造函数的问题?

难道使用构造函数方式创建对象就是完美的吗?不是的,通过构造函数创建出来的对象都有自己的方法,虽然他们实现的功能都是一样的?但是他们都有自己独立的引用,占着独立的内存。这就是构造函数创建对象的问题。

有人提出过这样的解决方法:

function sayName(){
  console.log(this.name);
}
function Person(name,age){
  this.name=name;
  this.age=age;
  this.sayName=sayName;
}

把方法的定义提到构造函数外部的全局作用域中,这样,创建出来的对象实例引用的就是同一块内存空间的方法了。看似挺好,但是也污染了全局。如果一个实例有多个方法,代码不容易很好的放在一起。

【原型模式】

function Person(name,age){
  this.name=name;
  this.age=age;
}
Person.prototype.sayName=function(){
  console.log(this.name)
}
let person1=new Person('zhangsan',18)
let person2=new Person('lisi',19)

// console.log(person1)
person1.sayName()

原型就是为了在对象实例间共享属性和方法而诞生的。以上,解决了构造函数的问题,他把需要共享的方法和属性放在了一个对象上(原型对象),也不会污染全局作用域。

关于原型的理解和原型的注意点,这几天我将重新写一篇文章,可以关注我的动态。

【class类模式】

class Person{
  constructor(name,age){
    this.name=name;
    this.age=age;
  }
  sayName(){
    console.log(this.name)
  }
}
let person1=new Person('zhangsan',18)
let person2=new Person('lisi',19)

// person1.sayName()
console.log(person1.sayName===person2.sayName) //true
// Person.prototype.sayName()

类模式是es6推出的,就是为了解决之前几种模式的缺点,可以理解为class是一种语法糖。

其实呢,类的本质就是一个函数。

相关文章:

  • 人形机器人发展趋势粗谈
  • 模型上下文协议MCP的缺点与潜在问题。
  • 【antd + vue】Tree 树形控件:默认展开所有树节点 、点击文字可以“选中/取消选中”节点
  • 代码随想录第15天:(二叉树)
  • 企业指标设计方法指南
  • Matlab 汽车ABS的bangbang控制和模糊PID控制
  • Linux 安装 vscode
  • erlang的安装-linux
  • 工业相机使用笔记
  • “实时滚动”插件:一个简单的基于vue.js的无缝滚动
  • 懒人版)RF_NSGA2_Topsis随机森林做代理预测模型NSGA3结合熵权法Topsis反求最佳因变量和对应的最佳自变量组合(含帕累托前沿解)
  • 腾讯会议for flatpak
  • 小张的工厂进化史——工厂模式
  • Linux基础命令解释
  • 北斗导航 | 接收机自主完好性监测(RAIM)算法学习思路总结及其算法研究:理论、实现与验证
  • SpringBoot连接MQTT客户端
  • PODS_ROOT、BUILT_PRODUCTS_DIR和SRCROOT有什么区别
  • js鼠标拖拽 修改el-table表格顺序 vue2 + element-ui js
  • Python 装饰器(Decorator)
  • 解锁 HTML5 表单新力量:<datalist>、<keygen>、<output>元素深度解析
  • 湖北大网站建设/有没有免费的推广网站
  • 广州做蛋糕的网站/seo深度优化公司
  • 论坛型网站怎么做的/活动推广方案怎么写
  • 郑州做网站的公司排名/品牌推广策略包括哪些内容
  • 百度云网站建设教程/镇江网站关键字优化
  • 专用主机网站建设/如何进行网络推广