12.js new操作的过程

277 阅读1分钟

NEW操作符做了哪些事情

  1. 创建一个新对象

  2. 将空对象的原型,指向于构造函数的原型 【Object.setPrototypeOf()】

  3. 将空对象作为构造函数的上下文(改变this指向)【构造函数就是new后面的那个函数呀,apply】

  4. 对构造函数有return返回值的处理判断 //如果return基本类型就忽略,如果return引用类型,就是引用类型

function Foo (){
    this.name="c"
    // return [1,2]
    // return {} 
    return '1111'  
}

let f = new Foo
console.log(f) // [1,2]
console.log(f) // {}
console.log(f) // Foo {name: 'c'}
// 如果return基本类型就忽略,如果return引用类型,就是引用类型

自己实现

// 自己实现

function Fun(age,name){
    this.age = age
    this.name = name
}
// ...arguments  是数类组对象

function create(fn,...arguments){
    console.log('arguments',arguments)
    // 1.创建一个空对象
    let obj = {}
    // 2.将空对象的原型指向构造函数的原型
    Object.setPrototypeOf(obj,fn.prototype)
    // 3.改变this指向,将空对象作为构造函数的上下文
    var result = fn.apply(obj,arguments)
    // 4.将构造函数有返回值的做处理
    return  result instanceof Object?result:obj
}

console.log(create(Fun,18,'s'))  //Fun {age: 18, name: 's'}
// let p = new Fun(18,'c')
// console.log(p)

// Object.setPrototypeOf(),为现有对象设置原型,返回一个新对象
// 接收两个参数:第一个是现有对象,第二是原型对象。

new出来的实例的__proto__指向的是new的prototype

new操作符和Object.create的区别

1.原型不一样

function aa (){}
aa.prototype = {
    a_fn:function(){
        this.aa="aaaaaaaa"
    }
}
let a = new aa()

console.log(aa)  // ƒ aa (){}
console.log(new aa())  // aa {}
console.log(new aa().__proto__ == aa.prototype)  // true

// const bb = Object.create({b:'bbbbbbb'})//传进去的就是__proto__的指向
const bb = Object.create(null)
console.log(bb)  // {}  No properties,


const c = {c:'cccccccc'}
const cc = Object.create(c)
console.log(cc) // {}   [[Prototype]]: Object  c: "cccccccc"
console.log(cc.__proto__ == c)  // true


// 效率:巨说new操作符,每秒可以生成23861个实例,而Object.create每秒可以生成663个实例,相差43倍

效率