解剖前端面试之原型链
2020-03-26 本文已影响0人
小遁哥
我这个人还是比较务实的,像借用构造函数、原型继承、组合继承、寄生式继承这些前前后后文章读了几篇,我印象最深的是:
function Father() {
this.numbers = ["1", "2", "3", "4"];
}
function Son() {
Father.call(this);
}
const son = new Son();
console.log(son.numbers);
console.log(son);
结果为:

numbers
是 son
自己的属性,而非从原型链上继承的再加上
Son.prototype = new Father()
,很棒,一个组合继承就实现了,此处应该有掌声。
随着前端技术的推进,很少能在用到prototype 这个字眼了
类型判断
在使用TS
时候不知道原生类型时,可以调用Object.prototype.toString.call
去查看,在开发工具里就可以完成,你不会把它写在代码里。
当你真的想要去判断类型,往往用typeof
加上===
、原生的Array.isArray
这些基本能满足你,或者你会用lodash
提供的方法,大概你不会用和prototype
有关系的instanceof
,写到这里我的眼眶竟有些湿润,众所周知,
[] instanceof Array
和[] instanceof Object
都会返回true
,可以看下这个视频再回来读这篇略带伤感的文章。
查找顺序
Vue.prototype.$axio = axios;
这种用法曾让我眼前一亮,尽管不是我自己想出来的,在组件中可以this.$axio
直接引用,用过React
后,我更喜欢import axios from 'axios'
这种写法,麻烦却直观。
首先会在实例上查找一遍,找不到会顺着原型链找,直到Object
Vue
2.5中也是利用了查找特性,在数组原型链上面加了一层,从而拦截splice
这些方法,战歌起!可以看下这个视频
原型链上的属性和方法是共享的 利用这个特性我们可以做一些统计和拦截的工作,多用于统一给ajax请求加前缀,不过有了axios
和webpack
自带的请求转发,通常不需要这么做,仍可用于一些hack手段。
当调用[].join
时应意识到join
是原型链上的方法
下面只是为了举个列子,实际情况下尽量不要去弄。
Array.prototype.username = "1";
const join = Array.prototype.join;
Array.prototype.join = function() {
console.log("调用了join方法");
return join.apply(this);
};
console.log([1, 2, 3, 4].join());
console.log([].username);
Array.prototype.username = "2";
console.log([].username);
输出为:

区分属性在实例上还是在原型上
用hasOwnProperty
,比如一些深拷贝的面试题会用到。
原型链是重要的但也没必要过分细究