好好学习 ,天天向上。Are you ready?
传统继承
构造函数继承
call
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
call 方法的第二个实参对应 第一个形参 , 依此类推 ;(接受n个参数)
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数
apply 方法接受两个参数; 第二个参数是数组 => 可以理解为arguments对象;(接受2个参数)
不带参数的构造函数继承;
// function Father(){
// this.a = 1;
// this.b = 2;
// this.c = 3;
// this.d = 4;
// }
// function Son(){
// // this => Son 的实例化对象;
// Father.call(this);
// }
// var son = new Son();
// console.log(son);
带参数的构造函数继承;
// function CreateObject(name , age){
// this.name = name;
// this.age = age;
// }
// function ExtendCreateObject(name , age){
// CreateObject.call(this , name , age);
// }
// var extend = new ExtendCreateObject("wuyanzu","44");
// function ExtendCreateObject(){
// CreateObject.apply(this , arguments);
// }
// var extend = new ExtendCreateObject("wuyanzu","44");
// console.log(extend);
原型继承
对象的深浅克隆;
浅克隆 :简单的复制对象,如果对象其中一个属性是引用型变量,就会出现这种情况,因为引用型变量保存的是内存地址,所以其实后来操作的都是同一块内存,导致了数组内容都一样。 //地址的传递
// var obj = { a : 10 , b : 20 , c : {name:"我是对象中的对象"}};
// var clone = obj;
// console.log(obj == clone);
// var clone = {};
// for(var attr in obj){
// // console.log(attr , obj[attr]);
// clone[attr] = obj[attr];
// }
深克隆就是在克隆的时候判断一下属性的类型是不是引用型变量,如果是的话就用递归方法让它一层一层进去复制自己。
递归完成深克隆
// function deepClone(obj){
// var cloneObj = new Object();
// // 遍历要克隆的对象;
// for(var attr in obj){
// if(obj[attr] instanceof Object){
// cloneObj[attr] = deepClone(obj[attr]);
// }else{
// cloneObj[attr] = obj[attr];
// }
// }
// return cloneObj;
// }
// // console.log(deepClone(obj));
// var clone = deepClone(obj);
for in 继承
function Father(){};
Father.prototype.init =function(){
console.log("hello world");
}
function Son(){};
var father = new Father();
var son = new Son();
for(var attr in Father.prototype){
// console.log(attr);
Son.prototype[attr] = Father.prototype[attr];
}
son.init();
原型链继承
// function Foo(){
// }
// console.log(new Foo());
// var arr = new Array();
// var arr1 = new Array();
// var arr2 = new Array();
// var arr3 = new Array();
// console.log(arr);
// Array.prototype.myForEach = function(){
// console.log("我的foreach方法");
// }
// arr.myForEach();
// var arr = [];
// console.log(arr);
// var obj = {};
// function Foo(){
// }
// Foo.prototype.show = function(){
// console.log("我是show方法");
// }
// var foo = new Foo();
// // console.log(foo);
// // foo.show();
// function Soo(){
// }
// Soo.prototype = new Foo();
// var soo = new Soo();
// console.log(soo);
// soo.show();
例子:拖拽继承
function Drag(){}
Drag.prototype.init = function(ele_selector){
// 1. 选择元素 | 设置关键属性;
this.ele = document.querySelector(ele_selector)
// 2. 调用核心方法;
this.handleEvent();
}
Drag.prototype.handleEvent = function(){
this.ele.onmousedown = this.startDrag.bind(this);
this.ele.onmouseup = this.stopDrag.bind(this);
}
Drag.prototype.startDrag = function(event){
//console.log("开始拖拽");
var e = event || window.event;
this.offsetX = e.offsetX;
this.offsetY = e.offsetY;
document.onmousemove = this.doingDrag.bind(this);
e.preventDefault();
}
Drag.prototype.doingDrag = function(event){
// console.log("拖拽进行中");
var e = event || window.event;
var nLeft = e.clientX - this.offsetX;
var nTop = e.clientY - this.offsetY;
this.ele.style.left = nLeft + "px";
this.ele.style.top = nTop + "px";
}
Drag.prototype.stopDrag = function(){
// console.log("拖拽终止");
document.onmousemove = null;
}
var drag = new Drag();
drag.init("#box");
// var drag1 = new Drag();
// drag1.init("#box1");
function ExtendDrag(){}
ExtendDrag.prototype = new Drag();
ExtendDrag.prototype.doingDrag = function(event){
// console.log("重写")
var e = event || window.event;
var nLeft = e.clientX - this.offsetX;
var nTop = e.clientY - this.offsetY;
// 边界检测;
nLeft = nLeft <= 0 ? 0 : nLeft;
this.ele.style.left = nLeft + "px";
this.ele.style.top = nTop + "px";
}
var extendDrag = new ExtendDrag();
extendDrag.init("#box1");
ES6继承
传统语法配合ES6进行原型编写
// function Drag(){}
// Object.assign(Drag.prototype,{
// init(){},
// handleEvent(){}
// })
// console.log(Drag.prototype);
class
// class Drag{
// // 相当于构造函数;
// constructor(a,b){
// console.log("constructor(构造函数)优先执行",a,b) .constructor方法
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,一个空的constructor方法会被默认添加。
// }
// init(){
// }
// handleEvent(){
// }
// }
// // var drag = new Drag(1,2);
// // console.log(drag);
// class ExtendDrag extends Drag{ extend继承
// // 1. 更新构造函数;
// constructor(a,b){
// // console.log(a,b);
// super(a,b); // call; 父类的构造函数,用来新建父类的this对象。
子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
// }
// init(){
// console.log("我是覆盖的init");
// }
// }
// var extend = new ExtendDrag(1,2);
// console.log(extend);
// extend.init();