JavaScript之原型和继承

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lzghxjt/article/details/83217835

1、实现示例:

function Person(name, sex) {
    this.name = name;
    this.sex = sex;
}

Person.prototype = {
    name:'无名氏',
    sex:'未知',
    nation:'火星',
    getName: function() {
        return this.name;
    },
    getSex: function() {
        return this.sex;
    },
    getNation: function() {
        return this.nation;
    }
}

var people = new Person("Tom", "man");
alert(people.getName());    //使用构造对象时的name值
alert(people.getNation());  //使用原型中的nation值

        我们把函数Person(也就是创建自定义对象的函数)称为构造函数,Person.prototype称之为Person的原型,可以看出JavaScript通过构造函数和原型的方式模拟实现了类的功能。prototype本质上是一个JavaScript对象,并且每个函数都有一个默认的prototype属性。prototype原型中的属性可以被原型所属的类的自定义对象引用。

        如果将People理解为父类,要定义一个子类Employee继承父类原型中的属性。那么:

function Employee(employeeID,name,sex){
    this.employeeID = employeeID;
    this.name = name;
    this.sex = sex;
}

Employee.prototype = new Person();   //将Employee的原型指向父类的对象
Employee.prototype.getEmployeeID = function() {
    return this.employeeID;
};

//此时Employee的对象就可以调用Person中的方法
var boss = new Employee("001", "Jim", "man");
alert(boss.getEmployeeID());   //使用构造对象时的employeeID值
alert(boss.getName());   //使用构造对象时的name值
alert(boss.getNation());   //使用原型中的nation值

2、变量this:表示当前对象。如果在全局作用域内使用this,则返回当前页面对象window。如果在函数(方法)中使用this,则返回调用该函数的对象。可以使用call或apply重新指定this所代表的对象。

        ①在全局作用域内:

<script type="text/javascript">
    alert(this === window);   // true
</script>

        ②在函数内:

var fruit = "apple";   //定义一个全局变量,等价于window.fruit = "apple";
function test() {
    alert(this.fruit);
}
test();  //apple

        ③在方法内:

var obj = {
    fruit: "orange",
    test: function(){alert(this.fruit);}
};
obj.test(); // "orange"

3、对象的constructor属性:始终指向创建该对象的构造函数。

var a = new Array(1, 56, 34, 12);
alert(a.constructor===Array);  //true
var b = [1, 56, 34, 12];
alert(b.constructor===Array);  //true
var c = new Function();
alert(c.constructor===Function);  //true
var d = function(){};
alert(d.constructor===Function);  //true

var Foo = function(){};
var obj = new Foo();   
alert(obj.constructor.constructor === Function); //true

function Person(name) {
    this.name = name;
}
var p = new Person("Tom");
alert(p.constructor===Person);  //true

        如果修改Person的prototype,Person创建的对象的constructor依然为Person

function Person(name) {
    this.name = name;
}
//修改Person的原型,而不是全部覆盖其原型
Person.prototype.getName = function() {
    return this.name;
};
var p = new Person("Tom");
alert(p.constructor===Person);  //true

        但如果覆盖掉Person的prototype,Person创建的对象的constructor则变为Object

function Person(name) {
    this.name = name;
}
//覆盖Person的原型
Person.prototype = {
    getName: function(){
        return this.name;
    }
};  
var p = new Person("Tom");
alert(p.constructor===Person);  //false
alert(p.constructor===Object);  //true

        这是因为覆盖Person的prototype时实际做的操作是:

Person.prototype = new Object({
    getName: function(){
        return this.name;
    }
});

        所以对象的constructor指向的是Object而非Person,可以用以下方法修正这个错误:

Person.prototype.constructor=Person;

        特殊地:构造函数的原型的constructor也始终指向构造函数本身。

alert(String.prototype.constructor===String);   //true
alert(Array.prototype.constructor===Array);   //true
alert(Date.prototype.constructor===Date);   //true
alert(Number.prototype.constructor===Number);   //true
alert(Object.prototype.constructor===Object);   //true

function Person(name) {
    this.name = name;
}
alert(Person.prototype.constructor==Person);  //true

参考:Douglas Crockford《JavaScript语言精粹》

           http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html

猜你喜欢

转载自blog.csdn.net/lzghxjt/article/details/83217835