javascript之面向对象总结

JavaScript之面向对象总结

前言:在ECMAScript中是没有类的概念的,因此它的对象与基于类的语言中的对象不一样。ECMA-262把对象总结为:“无序属性的集合,其属性包含基本值、对象或者函数”。

1、理解对象

var person = new Object();
person.name = "张三";
person.age = 15;

person.say = function(){
    alert('hello');
}

上面经过Object构造函数建立了一个对象,并为它添加了三个属性。es6

ECMA对象的属性有两种:数据属性和访问器属性。函数

var person = {
    name: "聂赫留朵夫", // 数据属性
    age: 25
}
Object.defineProperty(person, "year", { // 访问器属性
    get: function(){
        return 1922;
    },
    set: function(value){
        this.age = 25 + value;
    }
})

数据属性:包含一个数据值的位置,能够再这个位置写入和读取值

数据属性有4个描述其行为的特性:this

  1. [[Configurable]]:表示可否经过delete删除属性从而从新定义属性,默认为true
  2. [[Enumerable]]:表示可否经过for-in循环返回属性,默认为true
  3. [[Writeable]]:表示可否修改属性,默认为true
  4. [[Value]]:包含这个属性的数据值,默认值为undefined
ps:要修改默认的特性,必须使用 Object.defineProperty

访问器属性:包含一对儿gettersetter函数,不包含数据值

访问器属性也有4个特性:prototype

  1. [[Configurable]]:表示可否经过delete删除属性从而从新定义属性,默认为true
  2. [[Enumerable]]:表示可否经过for-in循环返回属性,默认为true
  3. [[Get]]:读取属性时调用的函数,默认值为undefined
  4. [[Set]]:写入属性时调用的函数,默认值为undefined
访问器属性不能直接定义,必须经过 Object.defineProperty来定义

读取属性的特性,经过Object.getOwnPropertyDescriptor方法

2、建立对象

一、经过字面量或者Object构造函数code

var person = {
    name: "尤瓦尔•赫拉利"
}
var car = new Object();
car.name = "法拉利"

优势:不清楚
缺点:使用同一个接口,会产生大量的代码对象

二、工厂模式接口

function createPerson(name, age){
    var o = new Object();
    o.name = name;
    o.age = age;
    return o;
}
var p1 = createPerson("方鸿渐", 14);
var p2 = createPerson("墨带", 20);

优势:解决了建立多个类似对象的问题
缺点:很明显,你不知道建立的对象的类型是什么ip

三、构造函数模式get

function Person(name, age){
    this.name = name;
    this.age = age;
}
var person = new Person("智人", 25);

建立实例,必需要经过new关键字,new调用经历的步骤:原型

  • 建立一个新的对象
  • 将构造函数的this指向新的对象
  • 执行构造函数中的代码
  • 返回新对象

优势:能够将每一个实例都标识为一种特定的类型
缺点:每一个方法都要在实例上从新建立一遍

四、原型模式

function Person(){}
Person.prototype.name = "凯撒大帝";
Person.prototype.age = 500;

var p1 = new Person();
console.log(p1.name); // 凯撒大帝
var p2 = new Person();

特色:全部的属性都是被不少实例共享的,但这个也是一个缺点。这个共享对于函数来讲挺好,对于基本类型来讲也还能够(实例上添加的同名属性能够覆盖原型上的),可是对于引用类型来讲就是比较突出的问题了(修改一个,其他的也会被修改)。另外,这个模式省略了为构造函数传参的方便。

五、构造函数模式和原型模式组合使用

function Person(name, age){
    this.name = name;
    this.age = age;
}
Person.prototype.getName = function(){
    alert(this.name);
}
var p = new Person("贝多芬", 200);

这种是比较通用的一种方式,结合了构造函数模式和原型模式的优势,可是这种方式可能对于写OO语言的人来讲,有点儿不友好,毕竟这种写法有点儿独特。

六、动态原型模式

function Person(name, age){
    this.name = name;
    this.age = age;
    if (typeOf this.sayName !== "function") {
        Person.prototype.sayName = function(){
            alert(this.name);
        }
    }
}

这种模式的好处是把全部的属性所有都封装到一个函数里面,可是会对函数作一个检测,没有的状况下才会去建立

七、寄生构造函数模式

function Person(name, age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.printName = function(){
        console.log(this.name);
    }
    return o;
}
var p = new Person("贝多芬", 55);

这个模式的一个适用场景是改写原生的对象

八、使用es6

class Person {
    constructor(name){
        this.name = name;
    }
    printName(){
        console.log(this.name);
    }
}
const p = new Person("巴菲特")
相关文章
相关标签/搜索