【青训营】- 聊聊JavaScript · 原型,原型链,this

229 阅读1分钟

prototype

当函数声明时js引擎自动生成;用于挂载公共属性

function Person() {
    console.log('p')
}
var p = new Person()
console.log(p.__proto__ === Person.prototype) // ture

proto

__proto__对象的私有属性,相当于原型的key值;指向它所对应的原型

function Person() {
    console.log('p')
}
var p = new Person()
// p {__proto__: Person.prototype}

constructor

对象的构造函数,指向构造改对象的函数;
prototype.constructor仅仅可以用于识别对象是由哪个构造函数初始化的,仅此而已。

function Person() {
    console.log('p')
}
var p = new Person()
p.constructor === Person // true

js的尽头

function Person() {
    console.log('p')
}
var p = new Person()
// 对象
console.log(p.__proto__ === Person.prototype)
console.log(Person.prototype.__proto__ === Object.prototype)
console.log(Object.prototype.__proto__ === null)
// 函数
console.log(Person.__proto__ === Function.prototype)
console.log(Function.prototype.__proto__ === Object.prototype)
console.log(Object.__proto__ === Function.prototype)
console.log(Function.__proto__ === Function.prototype)

Object.prototype ---> 普通对象
Object.prototype ---> Function.prototype 函数原型

原型链的用途

js能够实现面向对象编程的基石
和作用域链的功能类似,可以再原型链上查找属性

call,apply

function nnn () {
}
 function aa () {
   function bb() {
     function cc() {
       console.log(this)
     }
     cc.call(nnn) // --->nnn
     cc() // window
   }
   bb()
 }
 aa()

函数执行this默认指向window
call改变this指向
apply和call的区别就是传参形式不同

模拟call,apply

 var p = {name: 'p'}
 function hello() {
   console.log(this)
 }
Function.prototype.myCall = function (ctx = window) {
  ctx.fn = this
  let args = [...arguments].slice(1)
  let result = ctx.fn(...args)
  delete ctx.fn
  return result
}
 hello.myCall(p)

bind

new操作符

function Person(name) {
    this.a = 123
    this.b = 667
    this.name = name
}
Person()
// 函数定义 scope0: ao {this: window, arguments: []}
var p = new Person(1,2,3)
function myNew(fun) {
    return function () {
        let obj = {
            __proto__ : fun.prototype
        }
        fun.apply(obj, arguments)
        return obj
    }
}
var p2 = myNew(Person)('asd')
console.log(p2.__proto__ === p.__proto__) // true

new操作符step1: 创建原型对象
step2: 调用构造函数,并改变this指向 step3: 返回创建好的对象

Object.create

var objectCreate = (function(){
    var Fn = {}
    return function (obj){
      Fn.__proto__ = obj
      return Fn
    }
  }())
  var p = {name: 'pepole'}
  var o = objectCreate(p)
  var o2 = Object.create(p)
  console.log(o.__proto__ === o2.__proto__) // true