diveDylan / blog

My blog, detail is in the issues list
2 stars 0 forks source link

面试的一些基础题 #10

Open diveDylan opened 5 years ago

diveDylan commented 5 years ago

new关键字的理解

1、下面代码输出了啥

function A(a) {
  this.a = a
  return { a: 2}
}
const a = new A(1)
console.log(a)

output:

{ a: 2}

这道基础题考验的new关键字到底做了啥,简单的说有三步:

  1. 更改了this的指向,指向当前创建的实例
  2. 继承了类的prototype
  3. 执行函数返回当前实例

一步一步验证这简单的说法是否正确:

function A(a) {
  this.a = a
  return { a: 2}
}
A.prototype.word = 'none'
const a = new A(2)
console.log(a)

可以得到下图的输出结果: image _proto_上并没有word属性,这里涉及到constructor的理解,构造函数默认会返回当前对象,即构造函数内部的this,当然也可以更改返回的对象,如果返回的对象不是this将不继承类的原型 ,具体可以参考阮一峰ES6 class constructor 讲解 验证一下这段理解:

function B(a) {
 this.a = a 
}
B.prototype.word = 'b'
const b = new B(1)
console.log(b)

打印出下图的对象 image

出现了word属性正面是ok的

实现关键字new

更改this指向,prototype继承, 返回一个实例

function newFn(fn, param) {
   const obj = {}
  fn.call(obj,params)
  obj.prototype = Object.create(fn.prototype)
  return obj
}
function C(a) {
   this.a = a
}
C.prototype.c = 'c'
const c = newFn(C, 2)

c输出如下图: image

理解原型链

如何理解原型链,以及理解原型链的链式调用,我个人理解为一个向上递归的链式查找,每个实例都有一个<prototype>指针指向继承的父类,单链表结构,每个指针内判断是否存在该属性,否则向上插座直至没有这个指针返回undefined

function findPrototype(object, prop) {
         if (object[prop]) return object[prop]
        // __proto__不是标准,是chrome的完成
         if(!object.__proto__) return undefined
        findPrototype(object.__proto__, prop)
}
diveDylan commented 5 years ago

以下代码会报错吗或者输出啥

function log() {
 return a;
}
let a = 1:
log()

输出的应该是1,这题考的主要是TDZ暂时死区和函数的执行机制; 其实也可以换个思路解决,函数是会提升到最前面,函数的变量提升;

函数定义

将函数体作为字符串存入内存,函数明作为指针,形成一对键值对

函数执行

生成一个函数环境执行栈,在栈环境内开辟一块作用域,解析字符串为js执行代码,最后根据情况销毁这个执行栈

diveDylan commented 4 years ago

如何实现一个自定义的instance,还是蛮有趣的一件事,这个面试题完全来自于MDN

class MyArray {
  static [Symbol.hasInstance] (instance) { // instance 实例
        return Array.isArray(instance)
 }
}