javascript 中的继承实现, call,apply,prototype,构造函数

javascript中继承可以通过call、apply、protoperty实现

1.call

call的含义:

foo.call(thisObject, args...)

表示函数foo调用的时候,上下文切换为thisObject,意思是用thisObject来调用foo方法,如果没有指定thisObject,则外部的Global对象被用作默认的thisObject

function foo() {
    if (!this.s_name) { // 避免被this的属性重新赋值
        this.s_name = "inside foo";
    }
    console.info(this.s_name);
}

function bar() {
    if (!this.s_name) {
        this.s_name = "inside bar";
    }
}

var p = new bar();
foo.call(p);// foo函数调用,由于使用了call,其上下文切换成p,foo函数中的this指向p

output:inside foo

用call来实现继承:

/**
 * Created by Administrator on 2016/12/4 0004.
 */

function Person() {
    this.s_name = "Person"
    this.s_age = undefined;
    this.s_gender = undefined;
    this.f_say = function (txt) {
        console.info("%s say:%s", this.s_name, txt)
    }
}
// Person test
var p = new Person();
p.f_say(‘hello‘); // Person对象的正常调用

// Man 继承了Person中所有的属性和方法
function Man() {
    Person.call(this, this.arguments);// 这里理解下,Person()函数调用过程中,this执行Man,this.f_say=function(){}其实就是给Man执行的,可以认为给Man添加了几个属性和方法
    this.s_name = "Man"; // 注意,如果这句话放在第一行,将被Person的构造函数中的this.s_name = "Person"重新赋值
    this.f_playGame = function () {
        console.info("Man like play game");
    }
}
// Man test
var p_man = new Man();
p_man.f_say("hello"); // Man继承了Person中的f_say成员方法

 

2.apply,除了参数不同,和call完全一样,这里还是介绍下

apply的含义:

foo.apply(bar, tuple_arg)

表示调用foo函数的时候,内部涉及到this的都指向bar,这个例子要比前面的call的例子好

// apply
function foo(arg1, arg2) {
    this.s_name = "foo";
    this.f_func = function (arg1, arg2) {
        console.info(this.s_name + " " + arg1 + " " + arg2);// 这里的arg会按照作用域链和原型链综合查找
    }
}

function bar() {
    this.s_name = "bar";
}

var f = new foo("foo_arg1", "foo_arg2");
var b = new bar();
f.f_func.apply(b, ["apply_arg1", "apply_arg2"]); //调用foo类型的对象f中的f_func 方法,但是里面的this.s_name 其实是bar类型的对象b的
output:
bar apply_arg1 apply_arg2

继承的例子就不写, 和call一样,在Man()方法中调用Person.apply(this, []), 从而将Person() 中的this.* = * 执行了一遍,this其实是Man()

3. js原型(prototype)实现继承,具体的原理稍微有点复杂,可以查询其他资料

function Person() {
    this.s_name = "Person";
    this.f_say = function () {
        console.info(this.s_name)
    }
}

function Man() {
    this.s_name = "Man";
}

Man.prototype = new Person()

var p = new Man();
p.f_say();

output:
Man

4.构造函数

该方法和call 以及apply其实一个意思,只不过通过不同的途径来保证父函数执行时,里面的this是自己

 

function Person() {
    this.s_name = "Person";
    this.f_say = function () {
        console.info(this.s_name);
    }
}

function Man() {
    this.parent_method = Person;
    this.parent_method(this.arguments); // 执行时Person函数,里面的this其实是Man

    this.s_name = "Man"; // 如果放在第一行,会被Person() 的执行覆盖
}

var p = new Man();
p.f_say();

output:
Man

 

 

时间: 2024-11-05 18:33:07

javascript 中的继承实现, call,apply,prototype,构造函数的相关文章

JavaScript学习13 JavaScript中的继承

JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式:对象冒充 function Parent(username) //父类对象 { this.username = username; //下面的代码最关键的部分就是将子对象的this传递给了父对象 this.sayHello = function() { alert(this.username); } } f

javascript 中实现继承的六种方式

javascript 中对于继承的描述: 许多面向对象语言都支持两种继承的方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.在 javascript 中由于函数没有签名也就无法实现接口继承,而只支持实现继承,而且实现继承主要通过原型链来实现的. 先引述下官方文档对于原型链的描述:其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.要理解这个概念要先弄清楚构造函数,原型,和实例的关系:每个构造函数(只要是函数)都有一个 prototype 属性该属性指向一

JavaScript中的继承(原型链)

一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.property = true; } SupType.prototype.getSupvalue = function() { return this.property; }; function SubType() { this.subproperty = false; } //原型对象等于一个类型的实例

javascript 中各种继承方式的优缺点 (转)

javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现.下面对各种实现方式进行分析,总结各自的优缺点. 一 原型继承 let Super = functioin(name) { this.name = name; this.setName = (newName) => { this.name = name; }; this.getName = () => { return this.name; } } let Sub = function(sex) { this.se

JavaScript中的继承机制

JavaScript到底是不是面向对象的?! 有人说是,有人说基于对象更准确,因为JavaScript没有类.不去管它,但JavaScript确实提供了一些面向对象的机制. 本文主要讨论JavaScript中的继承.继承,简单来说,就是让子类获得父类的属性和方法,以达到共享和复用的目的. 在开始继承之前,首先需要创建父类.为了后续讨论的需要,我分别为父类创建了私有对象.实例对象.引用对象和两个实例方法. 创建父类的代码如下: // 父类实例的构造函数 function Pet(name,soun

javascript中实现继承的几种方式

javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Child1(){ Parent1.call(this); this.type = "child1"; } 缺点:Child1无法继承Parent1的原型对象,并没有真正的实现继承(部分继承) 2.借用原型链实现继承 function Parent2(){ this.name = "p

JavaScript中的bind,call和apply函数的用法和区别

一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下 首先要理解的第一个概念,JavaScript中函数调用的方式,总结下来,有以下4种 1. 方法调用 2. 正常函数调用 3. 构造器函数调用 4. apply/call 调用 要明白的第2个概念, JavaScript 中的函数,无论是上面哪种函数调用方式,除了你函数声明时定义的形参外,还会自动给函数添加两个形参,分别是this 和 arguments 要明白

前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的影响,单单是自己的念想受到了一定得局限,想法不能够像平地而起的高楼大厦建成一样.可是那大楼也是有烂尾的呀,我觉得最重要的还是外在环境与个人观念的先决条件,决定了拖延症的症状的好坏,有那么一些人,它也有拖延症,但是它在拖的中间,想的更多,看的更远.事情在做的时候更加有条不紊,这拖延症这样看来,它也是好

Javascript中的继承与Prototype

之前学习js仅仅是把w3school上的基本语法看了一次而已,再后来细看书的时候,书中会出现很多很多没有听过的语法,其中一个就是js的继承以及总能看到的prototype.我主要在看的两本js书是<javascript权威指南>,也就是那本犀牛书,还有一本是疯狂xx系列的<疯HTML5/CSS3/Javascript讲义>.前者非常适合用啃js细节,如果需要深入学习一些js内部机制以及相关的内容,这本大块头啃起来还是挺有味道的.后者是本速成教材,可以让你对某个概念有一个非常舒服的打