CPPAlien / JS-QA

前端知识问答
0 stars 0 forks source link

js 中的 new 的作用 #35

Open CPPAlien opened 4 years ago

CPPAlien commented 4 years ago

当代码 new Foo(...) 执行后,会又以下操作。

  1. 会创建一个新对象,该对象的 proto 等于 Foo.prototype;
  2. 把 Foo 中的 this 字段拷贝到新的对象上;
  3. 如果 Foo 有返回一个 object,则该 object 是整个 new 的返回值。如果无 return,则会保留第一步的规则。
f = function (string) { this.status = string};
f("a")                     // undefined,因为没有用 new,没有指向第二步,绑定 this
new f("a").status // "a",因为返回了一个新对象,并且 this 被拷贝到新对象上。

用闭包实现 private 属性

var f = function (status) {
  var value = status;
  return {
      get_value: function () { return value }
  }
}
f("a").get_value()   //"a"
CPPAlien commented 4 years ago

class 是个 function 的语法糖,默认使用 use strict (this 指针不默认指向全局)。里面的方法,相当于在这个 Function 的 prototype 中,而字段相当于挂在这个 Function 的 this 上。new 在 class 上创建对象的过程,相当于执行在这个函数的 constructor 的过程,其他同直接在函数上的 new。

class test {
   print() {
     this.realPrint()
   }

   realPrint() {
     console.log('xxxx')
   }
}

const a = new test();
a.print();  // 正确,因为进行了隐式绑定
const {print} = a;
print();  // 报错
class Index {
    constructor() {
    }

    print() {
        console.log('aa')
    }
}

console.log(new Index().print())  // 'aa'

当 constructor 有返回时,会报错

class Index {
    constructor() {
             return {

            }
    }

    print() {
        console.log('aa') 
    }
}

console.log(new Index().print())  // TypeError: (intermediate value).print is not a function

可以在 constructor 中 使用 this.print = this.print.bind(this) 的方法,或者把 print 写成箭头函数。

CPPAlien commented 4 years ago

Function 本身是一个对象,当一个函数对象被创建时,新函数对象被赋予一个 prototype 属性,值是包含一个 constructor 属性并且属性值为该新函数的对象。

所以当执行 new 获得一个新对象后,新对象的 constructor 也依然指向函数本身;

let Person = function() {}
let p = new Person()
p.constructor === Person // true