前言:大概从8月份开始就接触H5项目了,所用到的代码就是JS,所以准备找个时间 来总结下JS的一些基本知识.
第一部分:关于JS的apply与call方法
一开始也是被网上的各种资料弄的云里雾里的,最后发现了一篇不错的博文,于是按照自己的理解,敲了一些代码,终于算是有了一定的认识了.
传送门:http://blog.csdn.net/myhahaxiao/article/details/6952321 这篇博文总结的不错,下面开始正式的总结
简述:
ECMAScript规范给所有函数都定义了Call()与apply()两个方法,call与apply的第一个参数都是需要调用的函数对象,在函数体内这个参数就是this的值,剩余的参数是需要传递给函数的值,call与apply的不同就是call传的值可以是任意的,而apply传的剩余值必须为数组。
下面就以call为示例进行解析.apply和call没有太大的区别(当然了如果想彻底弄明白的,请看上方的传送门)
定义:以call为例
Function.call(obj,param1,param2...)
obj:这个对象将替代Function类里的this对象
params:这是一个参数列表
注意: 调用call的对象必须是一个函数对象,因为 call这个方法是在Function的prototype里的
作用与功能:
call和apply可以用来重新定义函数的执行环境
直白一点解释: obj夺舍了Function,拥有了执行Function的能力,并且this是指向obj的(个人认为夺舍这个词是很直观的-来源于网络)
代码分析:程序员拿代码说话,理论千万遍不如代码敲一遍,下面通过三段代码,来解释call的原理
var foo = {
name: 'myFoo',
showName: function() {
alert(this.name);
}
};
var myObj = {
name: 'Hello'
};
foo.showName.call(myObj);
/*执行结果:弹出 'Hello'
* 分析:foo.showName.call(myObj) 这段代码相当于是:
* 让myObj对象拥有了foo的showName方法(把foo的showName拷贝给自己了)
* 而myObj里的this指针式指向自己的(myObj)
* 所以才会输出 'Hello'---这是 myObj的属性
*/
2.
function Person(name, age) {
this.name = name;
this.age = age;
alert(this.constructor); //Student执行call时,这个thid指向Student
};
/*定义一个学生类*/
function Student(name, age, grade) {
this.name = '李四';
//arguments 对象是一个参数数组
//Person.apply(this, arguments); //argument是函数的参数数组
Person.call(this, name, age); //这样也可以
this.age = 23;
this.grade = grade;
};
//创建一个学生类
var student = new Student("张三", 21, "一年级");
//测试
alert(student.name + ',' + student.age + ',' + student.grade);
/*执行结果:
* 1.person里的alert弹出的是Student的构造函数
* 2.弹出 张三,23,一年级
*分析:构建Student对象时,遇到了call,于是从Person里面继承
*步骤:
* 1.进入Student构造函数,定义自己的属性
* 2.执行call时,将Person函数的属性继承过来(这时候this指向Student)
* (这时候自己已经定义好的属性就被覆盖了)
* 3.再次定义自己的属性,将Person中继承过来的属性再次覆盖
* (所以才会有以上结果:)Student的name(李四)属性被Person的张三覆盖了
* 而Person的age(21)属性被Student的23覆盖了
* 注意: Student里的this指针一直指向 Student
*
* */
3.
function Animal() {
this.name = "Animal";
this.showName = function() {
alert(this.name);
alert(this.constructor);
}
};
function Cat() {
this.name = "Cat";
};
var cat = new Cat();
var animal = new Animal();
//1.让cat对象拥有animal对象的一个showName函数,弹出结果是 'Cat'
animal.showName.call(cat);
//2.让cat对象重新继承整个Animal函数的所有属性
//所以cat自身属性会被覆盖,弹出结果是 'Animal'
Animal.call(cat);
cat.showName();
//注意:showName里面alert出的构造函数一直都是Cat函数
//证明这个showName其实是cat的showName