一、继承机制

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();

把 ClassB 的 prototype 属性设置成 ClassA 的实例
注意:调用 ClassA 的构造函数,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。
二、call & apply
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.Function.apply(obj,args)方法能接收两个参数  
call:和apply的意思一样,只不过是参数列表不一样.  Function.call(obj,[param1[,param2[,…[,paramN]]]])  

对象的继承,一般的做法是复制:Object.extend
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}

除此之外,还有种方法,就是:Function.apply或者Function.call。 通过 call() 或 apply() 方法可以设置 this 的值, 且作为已存在对象的新方法调用。

在 JavaScript 严格模式(strict mode)下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。
在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。

使用场景:

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对象里面

在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));

4、 封装对象时保证this的指向

var _this = this;
_this.$box.on('mousedown', function() {
return _this.fndown.call(_this);
})

5、代码优化

返回数组最大值

alert(Math.max(,))   //
alert(Math.max(,,,,,)) //
alert(Math.max([,,,])) // 找出数组中最大的元素,这样却是不行的。 function getMax(arr){
var arrLen=arr.length;
for(var i=,ret=arr[];i<arrLen;i++){
ret=Math.max(ret,arr[i]);
}
return ret;
} //这样写麻烦而且低效。如果用 apply呢
function getMax2(arr){
return Math.max.apply(null,arr);
}

两段代码达到了同样的目的,但是getMax2却优雅,高效,简洁得多。
apply会将一个数组装换为一个参数接一个参数的传递给方法。这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去 。 
//两个数组拼接,要把 arr2展开,然后一个一个追加到arr1中去
var arr1=[,,];
var arr2=[,,];
arr1.push(arr2)//[1,3,4,[3,4,5]]显然不行
//只能用一个循环去一个一个的push(当然也可以用arr1.concat(arr2),但是concat方法并不改变arr1本身)
var arrLen=arr2.length
for(var i=;i<arrLen;i++){
arr1.push(arr2[i]);
}
//使用apply,arr1执行push方法,arr2作为参数传入。arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合
Array.prototype.push.apply(arr1,arr2)

 
call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。因为 JavaScript 的函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。二者的作用完全一样,只是接受参数的方式不太一样 
function add(a, b){console.dir(this);}
function sub(a, b){console.dir(this);}
add(,); //"Window"
sub(,); //"Window"
add.call(sub, , ); //"sub(a, b)"
sub.apply(add, [, ]); //"add(a, b)"

javascript继承机制 & call apply使用说明的更多相关文章

  1. 【JavaScript】重温Javascript继承机制

    上段时间,团队内部有过好几次给力的分享,这里对西风师傅分享的继承机制稍作整理一下,适当加了些口语化的描述,留作备案. 一.讲个故事吧 澄清在先,Java和Javascript是雷锋和雷峰塔的关系.Ja ...

  2. javascript继承机制的设计思想(ryf)

    我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...

  3. 转:Javascript继承机制的设计思想

    我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...

  4. Javascript继承机制的设计思想

    转自:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.htm ...

  5. Javascript继承机制总结 [转]

    转自:http://bbs.csdn.net/topics/260051906 Javascript继承 一直想对Javascript再次做一些总结,正好最近自己写了一个小型Js UI库,总结了一下J ...

  6. javascript 继承机制设计思想

    作者: 阮一峰 原文链接:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_java ...

  7. JavaScript 继承机制小记

    读<JavaScript: the good parts>, 关于对象继承这块小记一笔: function Base(v){ this.baseValue = v; this.getBas ...

  8. Javascript继承机制的设计

    写软工作业时各种蛋疼:主要在于Javascript没有“子类”“父类”“接口”的概念,只能使用prototype来实现,看了下面一篇文章,感觉写得很不错~ http://www.ruanyifeng. ...

  9. Javascript prototype 及 继承机制的设计思想

    我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...

随机推荐

  1. 3dContactPointAnnotationTool开发日志(二四)

      添加了清空2d接触点的按钮,将输出的2d接触点的单位变成了像素,原点在图像的左下角.   对于obj文件的适配更加多样化了.

  2. 3dContactPointAnnotationTool开发日志(四)

      没办法,为了能在寝室接着做这玩意只好又在电脑上装一个和实验室版本一样的unity了.虽然打开后UI界面还是一团糟,不过至少要的东西都在,又手动调了调UI界面.   然后把旋转视角功能加上了.鼠标右 ...

  3. 【Redis】- 延时任务

    引言 在开发中,往往会遇到一些关于延时任务的需求.例如 生成订单30分钟未支付,则自动取消 生成订单60秒后,给用户发短信 对上述的任务,我们给一个专业的名字来形容,那就是延时任务.那么这里就会产生一 ...

  4. 第54天:原生js实现轮播图效果

    一.轮播图的原理: 一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏.通过计算偏移量利用定时器实现自动播放,或通过手动点击事件切换图片. 二.Html布局 首先父容器containe ...

  5. [九省联考2018]IIIDX 贪心 线段树

    ~~~题面~~~ 题解: 一开始翻网上题解看了好久都没看懂,感觉很多人都讲得不太详细,所以导致一些细节的地方看不懂,所以这里就写详细一点吧,如果有不对的or不懂的可以发评论在下面. 首先有一个比较明显 ...

  6. POJ2286:The Rotation Game——题解

    http://poj.org/problem?id=2286 题目大意:如图所示有一种玩具,每次可以拉动A-H的开关使得整个行(或列)向字母方向移动一位(如果移动到头的话则到行(列)尾部) 求使得中间 ...

  7. [Leetcode] minimum window substring 最小字符窗口

    Given a string S and a string T, find the minimum window in S which will contain all the characters ...

  8. 51nod 1215 数组的宽度&poj 2796 Feel Good(单调栈)

    单调栈求每个数在哪些区间是最值的经典操作. 把数一个一个丢进单调栈,弹出的时候[st[top-1]+1,i-1]这段区间就是弹出的数为最值的区间. poj2796 弹出的时候更新答案即可 #inclu ...

  9. [学习笔记]分治FFT

    一般的分治FFT是指: https://www.luogu.org/problemnew/show/P4721 考虑后面的f和前面的f有关系,但是贡献可以分着计算,逐一累计上去. 考虑cdq分治.算出 ...

  10. Redis、Memcache

    ★ Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sor ...