继承
继承
- 得到了父级的某些功能的使用权限;
- 模仿父级的某些功能,并使用这个功能;


克隆式继承
Son.prototype.pay = Father.prototype.pay;(深克隆)
Son.prototype = Father.prototype;(浅克隆)
克隆式继承的(for attr in father.prototype)
for(var attr in Father.prototype){
Son.prototype[attr] = Father.prototype[attr];
}
深克隆
var obj = {
a : {
b : {
c : {
name : 1
}
},
}
}
var clone = {};
var objString = JSON.stringify(obj);
clone = JSON.parse(objString);
这种方法有一个弊端,弊端就是没办法克隆函数
function foo(){
console.log(1);
}
console.log(foo.toString());
var functionString = foo.toString().replace(/^(function)(.+?)(\(\))/,"$1 $3");
let cloneFoo = eval("("+functionString+")");
console.log(cloneFoo);
深克隆函数 利用转换为字符串,在去挑函数名,重点用eval进行解析字符串!
自己封装的一个深克隆的方法
function deepClone(obj){
var clone = {}
for(var attr in obj){
// 如果当前要克隆的属性是对象;
if(typeof obj[attr] === "object"){
// 重新去克隆一份这个对象;
clone[attr] = deepClone(obj[attr])
}else if(typeof obj[attr] === "function" ){
// 函数深克隆;
var functionString = obj[attr].toString().replace(/^(function)(.+?)(\(\))/,"$1 $3");
clone[attr] = eval("("+functionString+")");
}else{
// 基本类型直接使用;
clone[attr] = obj[attr];
}
}
return clone;
}
原型链式继承
1. 实例; => 指针(原型指针) => 当前构造器(构造函数)的原型对象;
2. 原型; => 两个 => 1. constructor (指向当前原型所属的构造函数) ;
=> 2. __proto__ (原型里面也有原型指针) ; => Object.prototype;
原型链式继承的方法
1.不太兼容方式
Son.prototype.__proto__ = Father.prototype;
2.兼容方式
Son.prototype = new Father();
Son.prototype.constructor = Son;
3.智哥推荐写法(ES5)
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son;
4.工程化推荐使用(ES6)extends
class Son extends Father{
}
构造器继承
构造函数之中的继承 卧底式继承
重点关注this指向的问题!
function Father(name){
// this => son 的实例化对象;
this.type = "father";
this.name = name;
this.show = function(){
console.log(this.name +":"+"我最后悔的事情就是创建了阿里巴巴");
}
}
卧底的关键改变this指向利用(call,apply)
function Son(name){
// this => 实例化对象;
console.log(this);
// 构造器怎么给实例添加属性 ;
// this.xxx = xxx;
// 构造器的职责其实是代替Son对Son的实例化对象进行加工;
Father.call(this,name);
}
ES6 的构造器继承
class Father{
constructor(name){
this.name = name;
}
}
不改变constructor 或者 constructor 没有参数的情况可以直接继承;
class Son extends Father{
constructor(name,title){
super(name);
this.title = title;
}
}
var son = new Son( "Pony" , "用钱制造快乐" );
console.log( son );
如果需要更改 构造函数内的参数(增加或者忽略 ) 在class之中使用了constructor ,那么一定要在开头家加上super
改变不同需求的继承!例如拖拽式继承
首先利用推荐方式的原型链式继承 这个时候在对继承来的原型方法进行重写
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son;
Son.prototype.move = function(evt){
var e = evt || window.event;
var left = e.clientX - this.offsetX ;
var top = e.clientY - this.offsetY;
top = top < 0 ? 0 : top;
this.ele.style.left = left + "px";
this.ele.style.top = top + "px";
}
var son = new Son();
Son.init("#box3");
寄生式继承-->给原型链继承封装一下
一到面试题引发的惨案
obj.a === 1 && obj.a === 3 && obj.a === 5 && obj.a === 7 让其为true
监听对象属性
首先了解一个方法!
Object.defineProperty(obj, prop, descriptor)
该方法接收三个属性
obj : 对象;
prop : 监听的属性名;
descriptor : 配置参数;
配置的参数有:
1. configurable:当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
2. enumerable:当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
3. value该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
4. writable当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
5. get一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined。
6. set一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为 undefined。
重点是 get 和 set 方法,但注意在设置get和set的时,配置参数就不能设置value和writable,会产生冲突
这个方法可以让我们接触底层封装的Object,修改默认属性
var obj = {};
Object.defineProperty(obj,"a",{
// 是否属性可被删除;
configurable : true,
enumerable : true,
// value : "hahahahhaha",
// 是否可以通过 = 更改value值
// writable : false,
get: function(){
// console.log("property is getting",this);
// this.a === undefined ? this.a = 10 : "";
this.aValue === undefined ? this.aValue = 1 : this.aValue += 2;
return this.aValue;
},
set : function(){
console.log("property is setting");
}
})
obj.a;
console.log(obj.a === 1 && obj.a === 3 && obj.a === 5 && obj.a === 7);
Object.defineProperties()
该方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。 和上面的方法很像
Object.defineProperties(obj, props)
该方法接收两个参数, 第一:对象 第二:接收可枚举属性相对应的所有属性。(例如)
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// etc. etc.});
此时:对象属性的设置和获取可以被监听了 随意监听事件,并设置获取事件;