资讯专栏INFORMATION COLUMN

js 中的 call / apply 方法详解和引用类型的继承

cod7ce / 1864人阅读

摘要:也就是说当使用后,当前执行上下文中的对象已被替换为,后续执行将以所持有的状态属性继续执行。借用的方法替换的实例去调用相应的方法。实现引用类型的继承其实没有类这一概念,我们平时使用的等严格来说被称作引用类型。

call 方法:
object.method.call(targetObj[, argv1, argv2, .....])

apply 方法:
object.method.apply(targetObj[, [argv1, argv2 .....]])

call 和 apply 的作用没有太大区别,仅是在调用时传递参数的方式不同,call 是按位置参数传递,apply 是传递一个参数数组。

call 和 apply 方法的作用如下:

以 targetObject 替换 object 引入当前的执行上下文中。

也就是说当使用 object.call(targetObj) 后,当前执行上下文中的 object 对象已被替换为 targetObj,后续执行将以 targetObj 所持有的状态属性继续执行。

借用 object 的方法:
targetObj 替换 object 的实例去调用相应的方法。

// Person 引用类型
function Person(name, age) {
    this.name = name;
    this.age  = age;
    // Person 的对象方法
    this.getName = function () {
        console.log(this.name);
    }
}

// Person 的原型方法
Person.prototype.getInfo = function (joinStr, endLine) {
    joinStr = joinStr || "-";
    endLine = endLine || "!";
    console.log(this.name + joinStr + this.age + endLine);
}

// Boy 引用类型
function Boy(name, age) {
    this.name = name;
    this.age  = age;
}

var lilei  = new Boy("lilei", 18);

// 调用 Person 的原型方法
// 注:原型方法和对象方法并不对等,虽然二者皆可被对象继承 但原型链上只有原型方法 没有对象方法
// 所以对象方法还是要以下面实例化一个对象的方式去调用,不能直接通过原型链访问
Person.prototype.getInfo.call(lilei, "-", "!");
Person.prototype.getInfo.apply(lilei, ["-", "!"]);

// 调用 Person 的对象方法
var person = new Person("none", 0);
person.getName.call(lilei);
person.getInfo.apply(lilei, ["-", "!"]);

Boy 虽然并没有定义 getName 对象方法,也没有 getInfo 原型方法,但我们可以方便的使用 call/apply 将 Person 的方法应用到 Boy 的实例上。call/apply 的语意其实是说 Person “喊” Boy 的实例过来使用自己的方法。

实现引用类型的继承:

Javascript 其实没有类这一概念,我们平时使用的 Array, Date, Math 等严格来说被称作 “引用类型”。我们可以方便的使用 call/apply 来实现引用类型的对象方法的继承,从而让代码更加的精简。

继承分为 对象继承 和 原型链继承 两部分

// Person 引用类型
function Person(name, age) {
    this.name = name;
    this.age  = age;
    // Person 的对象方法
    this.getName = function () {
        console.log(this.name);
    }
}

// Person 的原型方法
Person.prototype.getInfo = function (joinStr, endLine) {
    joinStr = joinStr || "-";
    endLine = endLine || "!";
    console.log(this.name + joinStr + this.age + endLine);
}

// ======================================================
// Boy 引用类型
function Boy(name, age) {
    // 对象冒充继承
    // 将 Person 的对象成员继承过来
    Person.call(this, name, age);
}

// 原型链继承
// 将 Person 的原型属性继承过来
Boy.prototype = new Person();
// ======================================================

var lilei  = new Boy("lilei", 18);

lilei.getName();
lilei.getInfo();
console.log(Boy.prototype.getInfo);

注意这里 call/apply 只是继承父原型的对象方法,原型方法还需要多带带的继承一次。

平时开发中比较经典的用例就是:

Array.prototype.slice.call(document.getElementsByTagName("p"));

如上代码会返回一个DOM元素数组,document.getElementsByTagName("p") 获取到的并不是真正意义上的数组,没办法使用 pop 或 push 等方法,Array.prototype.slice 的实现大致如下:

Array.prototype.slice = function (start, end) {
    var temp  = [];
    var start = start || 0;
    var end   = end || this.length - 1;
    
    for (var i = start; i <= end; i ++) {
        temp.push(this[i]);
    }
    
    return temp;
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88748.html

相关文章

  • JavaScript继承方式详解

    摘要:可以通过构造函数和原型的方式模拟实现类的功能。原型式继承与类式继承类式继承是在子类型构造函数的内部调用超类型的构造函数。寄生式继承这种继承方式是把原型式工厂模式结合起来,目的是为了封装创建的过程。 js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念。...

    Yangyang 评论0 收藏0
  • JavaScript 继承方式详解

    摘要:原型继承与类继承类继承是在子类型构造函数的内部调用父类型的构造函数原型式继承是借助已有的对象创建新的对象,将子类的原型指向父类。 JavaScript 继承方式的概念 js 中实现继承有两种常用方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) JavaScript不是真正的面向对象的语言,想实现继承可以用JS的原型prototype机制或者call和apply方法 在面...

    YuboonaZhang 评论0 收藏0
  • js原型继承

    摘要:举例说明组合继承组合继承利用原型链借用构造函数的模式解决了原型链继承和类式继承的问题。示例组合式继承是比较常用的一种继承方法,其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。 对js原型和继承的理解一直处于不懂-懂-不懂-懂-不懂。。。的无限循环之中,本来打算只是简单总结下js继承方式,可看了些网上的资料后,发现又不懂继承了。。。这篇文章只...

    Hujiawei 评论0 收藏0
  • 详解js继承(二)

    摘要:寄生组合式继承终于写到最后一个继承了,我们在之前讲了种继承方式,分别是原型链,借用构造函数继承,组合继承,原型式继承,寄生式继承,其中,前三种联系比较紧密,后面两种也比较紧密,而我们要讲的最后一种,是和组合继承还有寄生式继承有关系的。 前言 趁周末结束之前赶紧先把坑填上。上回我们说到了原型链,并且留下了几个思考题,先把答案公布一下。 在最后一个例子里,console.log(b1.c...

    evin2016 评论0 收藏0
  • JavaScript面向对象核心知识归纳

    摘要:一面向对象概念面向对象就是使用对象。因此在构造函数中表示刚刚创建出来的对象。在构造函数中利用对象的动态特性为其对象添加成员。 一、面向对象 1.1 概念 面向对象就是使用对象。面向对象开发就是使用对象开发。 面向过程就是用过程的方式进行开发。面向对象是对面向过程的封装。 1.2 三大特性 抽象性所谓的抽象性就是:如果需要一个对象描述数据,需要抽取这个对象的核心数据 提出需要的核心...

    TalkingData 评论0 收藏0

发表评论

0条评论

cod7ce

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<