自行整理面试知识(JS篇)(二)

继承

原型链继承:

将子类的原型(prototype)连接到父类的实例,将子类的原始对象替换为父类的实例,从而拿到父类的所有方法和属性

不支持多重继承,因为prototype很明显会被新的父类替换

其次,创建子类实例的时候,无法向父类构造函数传递参数

同时,来自原型对象的引用属性是所有子类共享的,因为原型链向上寻找的时候共享了父类的实例

这显然不符合继承的原则

构造继承:

用call或者apply将父类中通过this绑定的属性和方法拷贝(借用)过来,又被称为用父类的构造函数增强子类

这里可以看到父类被子类调用,从而将子类中this指向父类。

function A(name){
    this.name = name;
}

function a(){
    A.call(this,"nickname");
    this.age = 12;
}
let aa = new a();
console.log(aa.name,aa.age);

很明显。这只能继承父类的实例方法和属性,不能继承其原型方法和属性。

组合继承:

ES6中extends的实现方式

前两者融合,用原型继承得到父类的原型方法和属性,用构造继承得到父类的实例方法和属性。

function A(name){
    this.name = name;
}
A.prototype.printName = ()=>{
    console.log(this.name);
}
function a(name,age){
    a.call(this,name);
    this.age = age;
}
a.prototype = new A();
a.prototype.constructor = a;
let aa = new a("nickname",18);
console.log(aa.age,aa.name);
aa.printName();

注意,这里要修复原型对象的构造器的指向问题,很明显,由于a的原型对象是父类A的实例对象,这个实例对象的原始构造函数很明显是A,但是a的原型对象的构造函数本应当是a本身,这里就应该做一次重新的指定。

几乎没有什么大问题,除了调用了两次父类的构造函数(后来的子类实例属性和方法覆盖了父类的实例属性和方法),消耗了点内存

寄生组合继承:

function A(name){
    this.name = name;
}

function a(name,age){
    A.call(this,name);
    this.age = 12;
}

(
    function super(){};
    super.prototype = A.prototype;
    a.prototype = new super();
)()

let aa = new a("nickname",18);

用一个空的没有实例方法和属性的super砍掉父类的实例方法和属性,解决了组合继承那多出来的一点内存,但是实现比较复杂

this

函数被谁调用,this就指向谁。

所以this是根据函数运行时的环境决定的,而不是这个函数被创建时决定的。

匿名函数的this是指向window的,你可以认为这里是来自window的调用(包括延时函数,是绑定在window上的方法,也是window做的调用)

在使用call和apply,bind的时候,this会被指定,以改变某个函数运行时候的上下文(改变被调用函数的this,让其this指向第一个参数),实际上也就是让第一个参数去调用函数,跟第一条规则丝毫不冲突。

的函数不改变当前this,所以你可以使用

function a(){
    this.name = "nickname";
    document.getElementById("123").addEventListener('click',(e)=>{
        console.log(this.name);
    })
}

这里要是使用匿名函数做回调函数,函数里的this应当指向触发事件的元素本身,也就是e.target,但是箭头函数不改变this,所以这里的this就指向a了。多用于react中传递给子组件的方法。

如果你想要用匿名函数达成同样的效果,你可以这样写

function a(){
    this.name = "nickname";
    let _this = this;
    document.getElementById("123").addEventListener('click',function(e){
        console.log(_this.name);
    })
}

数据类型

number,object,boolean,undefined,string,null,symbol标志一个变量独一无二

注意基本类型是:Number,String,Boolean,Undefined,Null,Symbol

以及函数类型:function

判断数据类型可以用typeof,但是[],{},null都会输出object

可以使用Object.prototype.toString.call(判断对象)来进行判断。

当然也可以使用constructor进行判断

比如  [].constructor === Array

还有instanceof

 

下一篇讨论js里常遇到的算法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值