JavaScript 进阶笔记

2017-07-03  本文已影响27人  罗小耳

一、使用prototype关键字和点标记法为构造器添加属性和方法

    // 定义一个名为Accommodation的构造函数
    function Accommodation() {}

    // 为这个类添加属性
    Accommodation.prototype.floors = 0;
    Accommodation.prototype.rooms = 0;
    Accommodation.prototype.sharedEntrance = false;

    // 为这个类添加方法
    Accommodation.prototype.lock = function () {}
    Accommodation.prototype.unLock = function () {}

    // 创建Accommodation类的对象实例
    var house = new Accommodation();
    var aparentment = new Accommodation();

    alert(house.floors);
    alert(aparentment.sharedEntrance);

    // 将对象实例的属性改为正确值
    house.floors = 2;
    aparentment.sharedEntrance = true;

    // 调用对象实例的方法
    house.unLock();
    aparentment.lock();

二、使用对象标记法直接来创建一个对象

 var house = {
        floors: 7,
        sharedEntrance: false,
        lock: function () {

        },
        unLock: function () {

        }
    };

    // 读取两个属性的值
    alert(house.floors);
    alert(house.sharedEntrance);

    // 调用lock方法
    house.lock();

    // 更新floors的属性
    house.floors = 10;

    // 动态添加一个新的属性 rooms
    house.rooms = 20;
    alert("floors==="+house.floors);
    alert("rooms==="+house.rooms);

三、通过对象直接量为构造函数添加属性和方法

// 定义一个名为Accommodation的构造函数
    function Accommodation() {

    }

    // 通过对象直接量为这个 类 添加属性和方法
    Accommodation.prototype = {
        floors: 0,
        rooms: 0,
        sharedEntrance: false,
        lock: function () {},
        unLock: function () {}
    }

    // 创建Accommodation类的对象实例
    var house = Accommodation();
    var apartment = Accommodation();

    // 读取对象实例的属性
    alert(house.floors);
    alert(apartment.sharedEntrance);
    
    // 将实例对象的属性值设为正确值
    house.floors = 2;
    apartment.sharedEntrance = true;
    
    // 调用对象实例的方法
    house.lock();
    apartment.unLock();

四、为已经存在的对象实例动态添加属性和方法

// 定义一个名为Accommodation的构造函数
    function Accommodation() {};

    // 通过对象直接量为这个类添加属性和方法
    Accommodation.prototype = {
        floors: 0,
        rooms: 0,
        sharedEntrance: false,
        lock: function () {

        },
        unlock: function () {

        }
    };

    // 创建一个实例对象
    var house = Accommodation();

    // 为类的原型动态添加一个新的方法
    Accommodation.prototype.alarm = function () {};

    // 已有的对象实例自动获得新的方法
    house.alarm();

五、组合使用this和prototype关键字编写高效的构造函数

function Accommodation() {
        // 利用this关键字来设置实例对象的属性
        this.floors = 0;
        this.isLocked = false;
    }

    // 利用prototype关键字来定义实例对象的方法
    Accommodation.prototype.lock = function () {
        // 通过原型定义的方法可以通过this关键字访问在构造函数中定义的属性
        this.isLocked = true;
    };

    Accommodation.prototype.unlock = function () {
        this.isLocked = false;
    }

    // 实例化一个Accommodation类型的对象
    var house = new Accommodation();
    // 执行lock方法
    house.lock();

    // 检查isLocked属性是否正确设置
    alert(house.isLocked);

六、用对象直接量作为构造函数的参数

function Accommondation(defaults) {
        // 如果没有传入值,默认为空的对象直接量
        defaults = defaults || {};

        // 如果defaults对象含有某个属性,就将实例对象中同名属性的值设置为defaults提供的值,否则设置为默认值
        this.floors = defaults.floors || 0;
        this.rooms = defaults.rooms || 0;
        this.sharedEntrance = defaults.sharedEntrance || false;
    }

    Accommondation.prototype.isLocked = false;

    Accommondation.prototype.lock = function () {
        this.isLocked = true;
    }

    Accommondation.prototype.unlock = function () {
        this.isLocked = false;
    }

    // 实例化两个Accommodation类对象,通过对象直接量传递命名的参数
    var house = new Accommondation({
        floors: 2,
        rooms: 10
    });

    var apartment = new Accommondation({
       floors: 1,
        rooms: 4,
        sharedEntrance: true
    });

七、用对象直接量作为构造函数的参数

function Accommondation() {}

    Accommondation.prototype.isLocked = false;
    Accommondation.prototype.lock = function () {
        this.isLocked = true;
        // 通过返回上下文,我们实际上返回了调用这个函数的那个对象的实例。因为这个对象包含了所有的方法,
        // 所以我们可以在本方法调用结束后马上调用其他方法
        return this;
    };

    Accommondation.prototype.unlock = function () {
        this.isLocked = false
        return this;
    };
    
    Accommondation.prototype.alarm = function () {
        alert("Sounding alarm!");
        return this;
    };

    // 创建一个对象实例
    var house = new Accommondation();
    // 我们得以将这些方法调用一个接一个地链接在一起
    house.lock().alarm().unlock();

八、通过原型继承创建一个子类
[当创建一个子类时,要确保子类的constructor属性指向子类本身的构造函数,因为从原型中直接复制过来的constructor值默认指向的是父类的构造函数]

// 定义一个两个方法的"类"
    function Accommondation() {}
    Accommondation.prototype.lock = function () {};
    Accommondation.prototype.unlock = function () {};

    // 定义一个构造函数,它将成为我们的子类
    function House(defaults) {
        defaults = defaults || {};
        // 将本"类"所有实例的floors属性初始化为2
        this.floors = 2;

        // 如果构造函数的对象直接量参数包含"rooms"属性,则使用传进来的值,否则默认为设为7个房间
        this.rooms = defaults.rooms || 7;
    }

    // 将House类的原型设为Accommodation类的一个实例
    // 使用关键字new来调用Accommodation的构造函数,这样就能创建并返回一个包含其所有属性和方法并返回一个包含其所有属性和方法的对象
    // 这个对象被传递给House类的原型,这样House类就得以继承Accommodation的所有内容

    House.prototype = new Accommondation();

    // 对象实例的constructor属性指向创建该对象的那个构造函数。然而,由于House继承了Accommodation的所有内容,
    // constructor的值也被赋值了,所以我们现在需要重置constructor的值,使其指向新的子类
    // 如果没有这一步,通过House类创建的对象就会报告说它们是通过Accommodation类创建的
    House.prototype.constructor = House;

    // 创建一个House实例,继承Accommodation的属性和方法
    var myHouse = new House();

    // 传入rooms的值从而在对象实例化时对rooms进行赋值
    var myNeughborsHouse = new House({
       rooms: 8
    });

    alert(myHouse.rooms);
    alert(myNeughborsHouse.rooms);

    // Accommodation的方法对House的对象也可用
    myHouse.lock();
    myNeughborsHouse.unlock();

    // 由于之前我们修改了constructor的值,所以由House创建的对象能如实报告这一点
    alert(myHouse.constructor === House);           // true
    alert(myHouse.constructor === Accommondation);  // false

    // instanceof关键字会沿原型链进行查询,所以也可用于检查一个对象实例是不是某个父类的子类
    alert(myNeughborsHouse instanceof House);              // true
    alert(myNeughborsHouse instanceof Accommondation);     // true
上一篇下一篇

猜你喜欢

热点阅读