classa由两部分组成构造函数和原型。
构造函数的部分,每个实例是独立的。
原型的部分,每个实例是共享的。
// 构造函数function classa(scolor) { this.color = scolor;}// 原型classa.prototype.saycolor = function () { alert(this.color);};
生成一个实例内部操作:
this 指向一个新 { }, 该对象的__proto__ 指向 classa.prototype。
执行构造函数 classa。
返回 this 指向的 { }。
var a = new classa();console.log(a.__proto__ === classa.prototype);// a 的继承对象指向 classaconsole.log(a.constructor === classa);
原型部分的继承function classb() { // 实现继承 classa 构造函数部分的继承}classb.prototype = new classa();// classb.prototype 指向新对象时,原有的 classb.constructor 属性会消失。// new classa().hasownproperty('constructor') 为 false,新生成的对象无 constructor 属性。// 在此修复这个问题。classb.constructor = classb;// 不过还存在 new classa().hasownproperty('color') 为 true 问题// 实现继承 classa 构造函数部分的继承,生成的属性优先级比 new classa().color 高,顾可以忽略
构造函数部分的继承--对象冒充把 classa 当做方法引入 classb ,此时两者共用一个 this。
执行构造函数 classa。
删除临时引入。
function classb(scolor) { this.newmethod = classa; this.newmethod(scolor); delete this.newmethod;}
构造函数部分的继承--apply/call/bind它是对象冒充的一种函数实现
把 classb 的 this 绑定到 classa 的 this 上,执行构造函数 classa。
function classb(scolor) { classa.call(this, scolor); // 以下两种方式效果一样,只是实现方式不同 // classa.apply(this, [scolor]); // classa.bind(this, scolor)();}
继承继承由两部分组成:构造函数的继承和原型的继承。任意选择继承方式组合即可。
构造函数的原型中的属性--constructor,永远指向该构造函数本身。如果继承时被修改,那么在最后请修正。
继承是保留原来的特性,所以可以在继承后,对新的构造函数或原型属性进行扩展。
date 的继承// 需要考虑polyfill情况object.setprototypeof = object.setprototypeof || function(obj, proto) { obj.__proto__ = proto; return obj; };/** * 用了点技巧的继承,实际上返回的是date对象 */function mydate() { // bind属于function.prototype,接收的参数是:object, param1, params2... var dateinst = new(function.prototype.bind.apply(date, [null].concat(array.prototype.slice.call(arguments))))(); // 更改原型指向,否则无法调用mydate原型上的方法 // es6方案中,这里就是[[prototype]]这个隐式原型对象,在没有标准以前就是__proto__ object.setprototypeof(dateinst, mydate.prototype); dateinst.abc = 1; return dateinst;}// 原型重新指回date,否则根本无法算是继承object.setprototypeof(mydate.prototype, date.prototype);mydate.prototype.gettest = function gettest() { return this.gettime();};let date = new mydate();// 正常输出,譬如1515638988725console.log(date.gettest());
// 继承的重点语句var dateinst = new(function.prototype.bind.apply(date, [null].concat(array.prototype.slice.call(arguments))))();// 使用经典方法实现继承的时候,由于 date 是内部对象,使用上有限制// 提示 “this is not a date object”// 说明 date 上的方法只能由 date 的实例调用,它会识别内部的 [[class]],浏览器无法修改。// 所以想到了如下方案var dateinst = new date(...arguments);// 能实现构造函数的只有 bindvar dateinst = new (date.bind(null, ...arguments))();// es5下无法实现 ...,只能转成数组[null].concat(array.prototype.slice.call(arguments));// 参数中带数组的只有 ayylyvar dateinst = new (function.prototype.bind.apply(date, [null].concat(array.prototype.slice.call(arguments))))();
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注!
相关推荐:
原生js写ajax的请求函数功能
以上就是关于js 继承的介绍的详细内容。