[关闭]
@Wangww0925 2019-08-07T07:53:18.000000Z 字数 5285 阅读 187

ECMAScript的核心语言 (二)类和模块 【 call() apply() 原型prototype 】

js-笔记


call() 和 apply(): 改变this的指向

注意: call与apply功能一致、继承性一致

两者区别:第二参数形式不一样

1、 改变this指向:

  1. var username = 'win';
  2. var age = 100;
  3. var obj = {
  4. username:'abc',
  5. age:12,
  6. show:function(){
  7. console.log(this.username + '今年' + this.age + '岁');
  8. }
  9. }
  10. var obj1 = {
  11. username:'www',
  12. age:18
  13. }
  14. function Show(){
  15. this.username = 'aaa';
  16. this.age = 10;
  17. }
  18. obj.show(); // 返回 abc今年12岁
  19. // call() 改变this的指向:
  20. obj.show.call(); // 返回 win今年100岁;没有参数,相当于this指向window
  21. obj.show.call(obj1); // 返回 www今年18岁; 此时this指向obj1
  22. obj.show.call(new Show()); // 返回 aaa今年10岁; 此时this指向Show
  23. // apply() 改变this的指向:
  24. obj.show.apply(); // 返回 win今年100岁;没有参数,相当于this指向window
  25. obj.show.apply(obj1); // 返回 www今年18岁; 此时this指向obj1
  26. obj.show.apply(new Show()); // 返回 aaa今年10岁; 此时this指向Show

2、 继承性:

  1. function Demo(){
  2. this.username = 'www';
  3. this.age = 18;
  4. this.show = function(){
  5. console.log(this.username + '今年' + this.age + '岁');
  6. }
  7. }
  8. function ShowCall(){
  9. Demo.call(this); // 通过call()进行继承
  10. }
  11. function ShowApply(){
  12. Demo.apply(this); // 通过apply()进行继承
  13. }
  14. // 通过call()继承的结果
  15. var show_call = new ShowCall();
  16. console.log(show_call.username); // 返回 www;继承了Demo的username
  17. console.log(show_call.age); // 返回 18;继承了Demo的age
  18. show_call.show(); // 返回 www今年18岁
  19. // 通过apply()继承的结果
  20. var show_apply = new ShowApply();
  21. console.log(show_apply.username); // 返回 www;继承了Demo的username
  22. console.log(show_apply.age); // 返回 18;继承了Demo的age
  23. show_apply.show(); // 返回 www今年18岁

3、 第二个参数的形式不同:

  1. call : call(this,user,age);
  2. apply : apply(this,[user,age]);

例子:

  1. function Tow(user,age){
  2. this.username = user;
  3. this.age = age;
  4. this.show = function(){
  5. console.log(this.username + '今年' + this.age + '岁');
  6. }
  7. }
  8. function ShowCallT(user,age){
  9. Tow.call(this,user,age); // call() 第二参数形式
  10. }
  11. function ShowApplyT(user,age){
  12. Tow.apply(this,[user,age]); // apply() 第二参数使用数组形式
  13. }
  14. // call()
  15. var show_call_T = new ShowCallT('www',18);
  16. console.log(show_call_T.username); // 返回 www
  17. console.log(show_call_T.age); // 返回 18
  18. show_call_T.show(); // 返回 www今年18岁
  19. // apply()
  20. var show_apply_T = new ShowApplyT('www',18);
  21. console.log(show_apply_T.username); // 返回 www
  22. console.log(show_apply_T.age); // 返回 18
  23. show_apply_T.show(); // 返回 www今年18岁

4、 就近原则:

  1. var index = 'a';
  2. function demo(){
  3. var index = 'b';
  4. console.log(index);
  5. }
  6. demo(); // 返回 b,优先使用局部变量
  7. demo('abc'); // 返回 b;形参类似于局部变量,同时出现就近原则

原型:

对象的原型 prototype:

-- 让公用的方法或者属性在内存中只存在一份

-- 每个函数在创建的时候都自动添加了prototype属性,这就是函数的原型

-- 原型也是对象

-- prototype是函数的内置属性 --作用于构造函数

通过new Array() 创建的对象的原型是 Array.prototype

通过new Date() 创建的对象的原型是 Date.prototype

通过直接量设置的对象 var a = true; 原型是 a.constructor.prototype

例子:

  1. function Info(name,age){
  2. this.name=name;
  3. this.age = age;
  4. }
  5. // 把方法添加到原型上
  6. Info.prototype.test = function(){
  7. console.log('ceshi');
  8. }
  9. var info1 = new Info('www',18);
  10. var info2 = new Info('abc',12);
  11. console.log(info1.test == info2.test); // 返回 true,让公用的方法或者属性在内存中只存在一份
  12. console.log(info2.constructor); // 返回 函数: function Info(name,age){ this.name=name; this.age = age;}

原型作用于构造函数:

访问的优先级:先访问自己的属性,如果没有往上查找执行,直到Object.prototype;

1、 给数组添加一个方法或者属性

  1. Array.prototype.test = function(){
  2. console.log('ceshi');
  3. }
  4. var arr = new Array(1,2,3);
  5. arr.test(); // 返回 ceshi
  6. ['a','b','c'].test(); // 返回 ceshi
  7. // 修改test
  8. arr.test = function(){
  9. console.log('你好');
  10. }
  11. arr.test(); 返回 你好

2、 给Object添加一个方法或者属性,使所有的对象有具有test方法

  1. Object.prototype.test=function(){
  2. console.log('ceshi');
  3. }
  4. 'abc'.test(); // 返回 ceshi
  5. [1,2,3].test(); // 返回 ceshi
  6. true.test(); // 返回 ceshi

获取对象的原型:

1、 constructor.prototype

  1. console.log('abc'.constructor.prototype); // 返回 String {}

2、 Object.getPrototypeOf() : ES5提供的新方法

  1. console.log(Object.getPrototypeOf('abc')); // 返回 String {}
  2. console.log(Object.getPrototypeOf([])); // 返回 Array[0]
  3. console.log(Object.getPrototypeOf(true)); // 返回 Boolean {}

原型链:

JavaScritp引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined.

1、 原型的继承:

  1. function User(){} 构造函数
  2. function Muser(){} 构造函数
  3. Muser.prototype = new User(); // 继承
  4. var obj = new Muser(); // 同时具有User和Muser的属性和方法

例子:

  1. // 定义一个武器
  2. function Weapon(){
  3. this.type = '武器';
  4. }
  5. // 定义剑
  6. function Sword(){
  7. this.size = '150cm';
  8. this.style = '刺';
  9. }
  10. // 定义刀
  11. function Knife(){
  12. this.size = '170cm';
  13. this.style = '砍';
  14. }
  15. // 剑继承武器、 刀继承武器
  16. Sword.prototype = new Weapon();
  17. Knife.prototype = new Weapon();
  18. // 定义一个倚天剑
  19. function Yitian(){
  20. this.hert = '12000';
  21. this.teji = '吸血';
  22. this.sex = '女士专用';
  23. }
  24. // 定义一把屠龙刀
  25. function Tulong(){
  26. this.hert = '800';
  27. this.teji = '暴击';
  28. this.sex = '男士专用';
  29. }
  30. // 倚天剑继承剑、屠龙刀继承刀
  31. Yitian.prototype = new Sword();
  32. Tulong.prototype = new Knife();
  33. // 得到倚天剑
  34. var yitian = new Yitian();
  35. console.log('倚天剑伤害:' + yitian.hert + ', 特技:' + yitian.teji + ', 攻击方式:' + yitian.style); // 返回 倚天剑伤害:12000, 特技:吸血, 攻击方式:刺
  36. // 得到屠龙刀
  37. var tulong = new Tulong();
  38. console.log('倚天剑伤害:' + tulong.hert + ', 特技:' + tulong.teji + ', 攻击方式:' + tulong.style); // 返回 屠龙刀伤害:800, 特技:暴击, 攻击方式:砍

2、 proto : 不是一个标准属性;不推荐使用

  1. console.log('abc'.__proto__); // 返回String {},IE不支持

原型中的this(本对象):

-- 调用方法的那个对象

给数字Number添加一个方法

  1. Number.prototype.add = function(){
  2. return this*2; // 直接修改
  3. }
  4. console.log((100).add()); // 返回 200
  5. console.log((200).add()); // 返回 400

给数组添加一个字符串拼接的方法(原型)

  1. Array.prototype.add = function(){
  2. var newArray = [];
  3. for(var i=0;i<this.length;i++){
  4. newArray[i] = this[i]
  5. }
  6. return newArray;
  7. }
  8. console.log(['a','b','c','d'].add()); // 返回 ["a", "b", "c", "d"]
  9. console.log([1,2,3].add()); // 返回 [1, 2, 3]

数组去重(原型)

  1. Array.prototype.unique = function(){
  2. var newArray = [];
  3. for(var i = 0;i < this.length; i++){
  4. if(newArray.indexOf(this[i]) == -1){
  5. newArray.push(this[i]);
  6. }
  7. }
  8. return newArray;
  9. }
  10. console.log([].unique()); // 返回 []
  11. console.log([1,1,2,2,4,4].unique()); // 返回 [1, 2, 4]

作者 wendy
2019 年 5月 23日


参考文献

JavaScript 中 call()、apply()、bind() 的用法

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注