一同进修面向对象——封装

组织函数内部:

tips:

在组织函数内部经由过程this(用于指向当前对象)变量增加属性或要领,
此处定义的属性和要领都是为对象本身所具有,
每次经由过程类建立实例时, this指向的属性都邑获得响应的建立.

var Person = function(name, sex) {
    // 私有属性: 只能被【私有要领】和【特权要领】接见
    var contact = 'xxxxx@qq.com';
    var number = '88888888';

    // 私有要领: 在组织函数里声明, 能被【私有函数】【特权要领】接见, 只能接见【私有要领】和【私有属性】
    var getInfo = function(name, sex) {
        console.log('My name is ' + name + ', I’m a ' + sex + '!');
        console.log('My email is ' + contact);
    };

    // 公有属性
    this.name = name;
    this.sex = sex;

    // 特权要领: 能够接见【私有属性】【私有要领】【公有属性】
    this.intro = function() {
        getInfo(name, sex);
    };
    this.getContact = function(number) {
        console.log(number);
    };

    // 组织器
    this.getContact(number);
};

组织函数外部:

tips:

经由过程点语法定义的属性和要领不会增加到新建立的对象,因而类的实例无法接见, 只能经由过程类的本身(Person)接见.

// 类静态公有属性(对象不能访)
Person.isChinese = true;

// 类静态公有要领(对象不能接见到)
Person.speak = function() {
    console.log('what???');
};

类的原型:

tips:

一种是为原型对象属性赋值, 另一种是将一个对象赋值给类的原型对象.
经由过程prototype继续的属性或要领是每一个对象经由过程prototype接见到的,
所以每次经由过程类建立实例时, 这些属性和要领不会再次建立.

Person.prototype = {
    // 显现指定对象的constructor属性
    constructor: Person,
    // 公有属性
    hobby: 'reading',
    // 公有要领
    sport: function() {
        console.log('run');
    }
};

// test:
var tony = new Person('Tony', 'man', '25');

console.log('--- 接见【公有属性】 ---');
console.log(tony.name);            // Tony
console.log(tony.sex);            // man

console.log('--- 接见【特权要领】 ---');
console.log(tony.intro());        // My name is Tony, I’m a man!
                                // My email is xxxxx@qq.com

console.log('--- 接见【类静态公有属性】和【类静态公有要领】 ---');
console.log(tony.isChinese);     // undefined
console.log(tony.speak());        // undefined

console.log('--- 经由过程类本身接见【类静态公有属性】和【类静态公有要领】 ---');
console.log(Person.isChinese);    // true
console.log(Person.speak());    // what???

console.log('--- 接见【公有属性】及【公有要领】 ---');
console.log(tony.hobby);        // reading
console.log(tony.sport());        // run


// 经由过程闭包完成:
var Person = (function() {
    // 静态私有变量
    var isChinese = true;

    // 静态私有要领
    var speak = function() {};

    // 建立类
    var _person = function() {
        // 私有属性: 只能被【私有要领】和【特权要领】接见
        var contact = 'xxxxx@qq.com';
        var number = '88888888';

        // 私有要领: 在组织函数里声明, 能被【私有函数】【特权要领】接见, 只能接见【私有要领】和【私有属性】
        var getInfo = function(name, sex) {
            console.log('My name is ' + name + ', I’m a ' + sex + '!');
            console.log('My email is ' + contact);
        };

        // 公有属性
        this.name = name;
        this.sex = sex;

        // 特权要领: 能够接见
        this.intro = function() {
            getInfo(name, sex);
        };
        this.getContact = function(number) {
            console.log(number);
        };

        // 组织器
        this.getContact(number);
    };

    // 构建原型
    _person.prototype = {
        constructor: _person,
        // 公有属性
        hobby: 'reading',
        // 公有要领
        sport: function() {
            console.log('run');
        }
    };

    // 返回类
    return _person;
})();

类的两种写法

  1. 规范原型写法

function Person() {}
Person.prototype.sayHi = function() {}

var me = new Person();
console.log(me.constructor === Person);    // true;
  1. 对象字面量

function Person() {}
Person.prototype = {
    sayHi: function() {}
}
var me = new Person();
console.log(me.constructor === Person);    // false;
console.log(me.constructor === Object);    // true;

运用对象字面量的瑕玷:

运用对象字面情势改写原型对象改变了组织函数的属性,因而它如今指向Object而不是Person.

缘由:

由于原型对象具有一个constructor属性,这是其他对象实例所没有的.
当一个函数被建立时,它的prototype属性也被建立, 且该原型对象的constructor属性指向该函数.
当运用对象字面情势改写原型对象Person.prototype时, 其constructor属性将被置为泛用对象Object.

处理:

在改写原型对象时手动重置其constructor属性.

    // 对象字面量修改:
    function Person() {}
    Person.prototype = {
        constructor: Person,
        sayHi: function() {
            console.log('Hi~');
        }
    }
    var me = new Person();
    console.log(me.constructor === Person);    // true;
    console.log(me.constructor === Object);    // false;

建立对象的平安形式

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

var tony = new Person('Tony', 'boy');
console.log(tony.name);     // Tony
console.log(tony.sex);        // boy

var anna = Person('Anna', 'girl');
console.log(window.name);     // Anna
console.log(window.sex);    // girl

console.log(anna);        // undefined
console.log(anna.name);        // Uncaught TypeError: Cannot read property 'name' of undefined

tips:

new能够看做是对当前对象this不停地赋值,
假如没有new, 则会直接实行函数, 由于函数在全局作用域中实行了,
所以在全局作用域中this指向的当前对象就自然是全局变量,
属性都增加到window上面了;
别的一个则由于Person类中没有return语句,
则函数实行完没有返回实行效果. 所以实例对象为undefined;

// 建立对象的平安形式
var Person = function(name, sex) {
    // 推断实行过程当中this是不是是当前对象(假如是申明是用new建立的)
    if(this instanceof Person) {
        this.name = name;
        this.sex = sex;
    } else {
        // 不然从新建立这个对象
        return new Person(name, sex);
    }
}
    原文作者:引路人
    原文地址: https://segmentfault.com/a/1190000006620758
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞