> 技术文档 > 【js(7)创建对象的三种写法】

【js(7)创建对象的三种写法】


创建对象的三种写法

  • 一、new操作符
    • 1.实现原理
    • 2.模拟new操作符的实现
  • 二、字面量
  • 三、Object.create
    • 1.实现步骤
    • 2.模拟实现
    • 3.Object.create()和new的区别

一、new操作符

在这里插入图片描述

1.实现原理

  • 创建了一个空对象,
  • 将空对象的原型,指向于构造函数的原型
  • 将空对象作为构造函数的上下文(改变this指向)
  • 对构造函数有返回值的处理判断(如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。)
 function Foo() { this.name = \'yang\'; return 111;//--->Foo {name :\'yang\'} 返回的是值类型忽略 return [1, 2, 3];// --->[1,2,3] 返回的是引用类型,new不起作用 } console.log(new Foo()); //console.log(Foo.prototype = new Foo().__proto__);//true

2.模拟new操作符的实现

 function Fun(age, name) { this.name = name; this.age = age; } //模拟new操作符 function create(fn, ...args) {//...args为参数数组 //1.创建一个空对象 var obj = {}; //2.将空对象的原型指向构造函数的原型 Object.setPrototypeOf(obj, fn.prototype); //3.将空对象作为构造函数上下文(改变this指向) //调用构造函数fn,并将this指向obj,将参数args传给fn //result为函数执行完的值(构造函数的返回值) var result = fn.apply(obj, args); console.log(result); //4.对构造函数返回值进行处理判断 return result instanceof Object ? result : obj; } console.log(create(Fun, \"Tom\", 20));

二、字面量

const obj = { key1: value1, key2: value2, method() { // 方法体 }};//举例:const person = { name: \"Alice\", age: 25, greet() { console.log(\"Hello, my name is \" + this.name); }};person.greet(); // 输出: Hello, my name is Alice

三、Object.create

  • Object.create()方法也是创建一个新的对象,使用传入的现有对象作为新建对象的__proto__属性的引用
var Parent = { name:\"Zong\"};let child = Object.create(Parent);console.log(child.name)//Zong//这里的\"Zong\"其实不是child自带的name属性,而是child顺着原型链找到的,child.__proto__ => Parent

1.实现步骤

  • 创建一个空的构造函数F
  • F的prototype对象指向传入对象的__proto__
  • new一个F的实例并返回

2.模拟实现

Object.create = function(proto){ let F = function() {}; F.prototype = proto; return new F();}

3.Object.create()和new的区别

  • ​ Object.creat()创建一个新的实例对象,该实例的实例原型指向Object.create()接收的参数本身
  • new 构造函数(),这个操作创建一个新的实例对象,该实例的实例原型指向构造函数的prototype
 var Parent = function () { this.name = \"Zong\" } var Parent2 = { name: \"zong\" }; let child1 = new Parent(); let child2 = Object.create(Parent);//传的是一个函数,而不是一个普通对象 console.log(child2.__proto__ === Parent);//true let child3 = Object.create(Parent2); console.log(child1);//Parent {name: \"Zong\"} console.log(child2);//Function {} console.log(child3);//{},这里返回了一个空对象(没有自身属性的对象) //但这个对象的__proto__.name为\"zong\"(可以访问Parent2上的属性)
  • 如果 Base 是一个构造函数(function),采用这种方法创建对象没有意义(只是让新对象的原型指向了构造函数本身)
  • 如果 Base 是一个实例对象或者字面量,那么相当于实现了对象的浅拷贝