一、继承机制
1、对象冒充:构造函数使用 this 关键字给所有属性和方法赋值,可使 ClassA 构造函数成为 ClassB 的方法,然后调用它。
function ClassZ() { this.newMethod = ClassX; this.newMethod(); delete this.newMethod; this.newMethod = ClassY; this.newMethod(); delete this.newMethod; }
这里存在一个弊端,如果存在两个类 ClassX 和 ClassY 具有同名的属性或方法,ClassY 具有高优先级。因为它从后面的类继承。除这点小问题之外,用对象冒充实现多重继承机制轻而易举。
2、apply()、 call() 方法是与经典的对象冒充方法最相似
function ClassB(sColor, sName) { //this.newMethod = ClassA; //this.newMethod(color); //delete this.newMethod; ClassA.call(this, sColor); this.name = sName; this.sayName = function () { alert(this.name); }; }
3、原型链
function ClassA() { } ClassA.prototype.color = "blue"; ClassA.prototype.sayColor = function () { alert(this.color); }; function ClassB() { } ClassB.prototype = new ClassA();
Object.extend = function(destination, source) { for (property in source) { destination[property] = source[property]; } return destination; }
除此之外,还有种方法,就是:Function.apply或者Function.call。 通过 call() 或 apply() 方法可以设置 this 的值, 且作为已存在对象的新方法调用。
使用场景:
1、 arguments 转换为数组
// 返回的是数组,但是arguments本身保持不变 vararg=[].slice.call(arguments); //[].slice.call(document.getElementsByTagName(‘li‘));
2、借用
var foo = { name: ‘joker‘, showName: function() { console.log(this.name); } } var bar = { name: ‘rose‘ } foo.showName.call(bar);
3、继承
var Student = function(name, age, high) { // use call Person.call(this,name,age); this.high=high; }
Person.apply(this,arguments);
this:在创建对象在这个时候代表的是student
arguments:是一个数组,也就是[“qian”,”21”,”一年级”];
用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面
4、 封装对象时保证this的指向
var _this = this; _this.$box.on(‘mousedown‘, function() { return _this.fndown.call(_this); })
5、代码优化
返回数组最大值
alert(Math.max(5,8)) //8 alert(Math.max(5,7,9,3,1,6)) //9 alert(Math.max([5,7,9,1])) // 找出数组中最大的元素,这样却是不行的。 function getMax(arr){ var arrLen=arr.length; for(var i=0,ret=arr[0];i<arrLen;i++){ ret=Math.max(ret,arr[i]); } return ret; } //这样写麻烦而且低效。如果用 apply呢 function getMax2(arr){ return Math.max.apply(null,arr); }
//两个数组拼接,要把 arr2展开,然后一个一个追加到arr1中去 var arr1=[1,3,4]; var arr2=[3,4,5]; arr1.push(arr2)//[1,3,4,[3,4,5]]显然不行 //只能用一个循环去一个一个的push(当然也可以用arr1.concat(arr2),但是concat方法并不改变arr1本身) var arrLen=arr2.length for(var i=0;i<arrLen;i++){ arr1.push(arr2[i]); } //使用apply,arr1执行push方法,arr2作为参数传入。arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合 Array.prototype.push.apply(arr1,arr2)
function add(a, b){console.dir(this);} function sub(a, b){console.dir(this);} add(1,2); //"Window" sub(1,2); //"Window" add.call(sub, 1, 2); //"sub(a, b)" sub.apply(add, [1, 2]); //"add(a, b)"
javascript继承机制 & call apply使用说明
原文:http://www.cnblogs.com/chenlogin/p/5140705.html