面向对象编程是每次面试必问的知识点,而前端js如何实现继承每次命中率高达80%
这不,近两天我们面试时候,同事就问道面试者此问题,但是,不论之前自己做的回答,还是面试者的回答,基本都不太令人满意
很大的原因是多数时候前端并不需要实现继承,就jquery来说也基本上是一码到底,没有实现继承,据我所知,也就prototype与ext实现过继承
所以继承对前端来说似乎不太适用
近两年来情况有所变化,SPA的兴起以及前端逻辑的复杂化,让前端代码愈发的多,愈发的重,所以继承慢慢的进入了一些初级一点的前端视野
所以,好好的了解如何实现继承,继承的几个用法,是非常有意义的,就算只是为面试都是很有用的
文章只是个人见解,有误请提出,demo未做检测,有误请提出
实现继承
当一个函数被创建时,Function构造函数产生的函数会隐式的被赋予一个prototype属性,prototype包含一个constructor对象
而constructor便是该新函数对象(constructor意义不大,但是可以帮我们找到继承关系)
每个函数都会有一个prototype属性,该属性指向另一对象,这个对象包含可以由特定类型的所有实例共享的属性和方法
每次实例化后,实例内部都会包含一个[[prototype]](__proto__)的内部属性,这个属性指向prototype
① 我们通过isPrototypeOf来确定某个对象是不是我的原型
② hasOwnPrototype 可以检测一个属性是存在实例中还是原型中,该属性不是原型属性才返回true
var Person = function (name, age) { this.name = name; this.age = age; }; Person.prototype.getName = function () { return this.name; }; var y = new Person('叶小钗', 30);
通俗一点来说,prototype是一模板,新创建对象就是对他一个拷贝,里面的属性或者方法都会赋值给实例
这里说是模板赋值其实不太合理,反正由类产生的所有实例的__proto__都会共享一个prototype,这里我做一个例子
我们在断点情况下是没有name2属性的,但是我们如果在断点下加上这个代码的话,a.name2,就有值了
Klass.prototype.name2 = '222';
所以,这里说模板,不如说是指针指向,都是共享一个对象;继承的情况的话就是这样
(function () { var Person = function (name) { this.name = name; }; //Person.prototype = {};//这句将影响十分具有constructor属性 Person.prototype.getName = function () { return this.name; }; var Student = function (name, sex, id) { this.name = name || '无名氏'; this.sex = sex || '不明'; this.id = id || '未填'; //学号 }; //相当于将其prototype复制了一次,若是包含constructor的话将指向Person Student.prototype = new Person(); Student.prototype.getId = function () { return this.id; } var y = new Person(); var s = new Student; var s1 = y instanceof Person; var s2 = s instanceof Student; var s3 = s instanceof Person; var s4 = Student.prototype.constructor === Person; var s5 = Student.constructor === Person; var s6 = Student.constructor === Function; var s = ''; })();