用面向对象的方式写JavaScript

最近看书,学习了一些JavaScript的高级用法。自认为高级,仅对于笔者这种前端新手来说,高手轻喷。

记录一下,方便自己后来查阅。

JavaScript没有类的概念,这跟其他纯正的面向对象语言是最大的区别。然而,这并不影响我们用面向对象的思维来写JavaScript代码。

首先,理解下Javascript的Object。直接上例子吧。

//最原始模式
var person = new Object();
person.name = "Jack";
person.age = 20;
person.sex = "male";

person.sayHi = function(){
    alert("Hello,everybody. My name is " + this.name + ".");
}

在例子中,我们创建了一个对象person,并添加了三个属性name,age,sex,和一个方法sayHi()。这是最原始的创建对象方式,后来,发现了一种高级点的写法:对象字面量语法。还是上例子。

//对象字面量模式
var person = {
    name: "Jack",
    age: 20,
    sex: "male",
    sayHi: function(){
        alert("Hello,everybody. My name is " + this.name + ".");
    }
}

看起来高端些了。然而上述两种方式都有个缺点,如果要创建多个person,会产生大量的重复定义代码。这肯定是我等洁癖程序员所不能容忍的。于是乎,开始引入设计模式。

//工厂模式
function buildPerson(name, age, sex) {
    var person = new Object();
    person.name = name;
    person.age = age;
    person.sex = sex;

    person.sayHi = function(){
        alert("Hello,everybody. My name is " + this.name + ".");
    }
    return person;
}

var person1 = buildPerson("Jack", 20, "male");
var person2 = buildPerson("Rose", 18, "female");

工厂模式解决了创建多个对象的问题。然而,还是有问题。没解决对象识别的问题。即person1,person2的对象类型是Object,而没法更精确。写法还要再改进:构造函数模式。上例子。

//构造函数模式
function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.sayHi = function(){
        alert("Hello,everybody. My name is " + this.name + ".");
    };
}

var person1 = new Person("Jack", 20, "male");
var person2 = new Person("Rose", 18, "female");

这个写法,是不是跟我们Java的类定义很类似了!而且我们调用下以下代码,可以发现也解决了工厂模式的对象识别问题。

alert(person1 instanceof Person); //结果为true

在我的水平看来,构造函数模式已经完美。然而,书本的大神还是狠狠的打了我几巴掌。“内存占用”,“内存占用”,“内存占用”!

在上面的例子中,每次new一个Person,都会实例化一个“sayHi”对象(在JavaScript中,函数也是对象)。

创建两个完成同样认为的Function实例的确没有必要;况且有this对象在,根本不用在执行代码前就把函数绑定到特定对象上面。

在构造函数模式中,我们调用以下代码可以验证到,确实创建了多个“sayHi”对象。

alert(person1.sayHi == person2.sayHi); // 结果为false

为了解决这个问题,我们需要再引入一个设计模式:原型模式。

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用户是包含可以由特定类型的所有实例共享的属性和方法。

 如果需要更深入的了解prototype,可以查看相关资料,这里就不细说了。

我们可以使用原型模式,来定义方法和共享的属性。来,例子。

//构造函数模式+原型模式
function Person(name, age, sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
}

Person.prototype = {
    constructor: Person,
    sayHi: function(){
        alert("Hello,everybody. My name is " + this.name + ".");
    }
}

var person1 = new Person("Jack", 20, "male");
var person2 = new Person("Rose", 18, "female");

我们在调用以下代码,会发现,person1和person2的sayHi是同一个对象,成功解决了构造函数模式的问题。

alert(person1.sayHi == person2.sayHi); // 结果为true

这种构造函数与原型混成的模式,是目前在ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法。

好了,先写这么多。其实书里讲到的对象方面的知识还很多,而且更深入。不过对于我这种水平的新手来说,以上知识足够消化和使用一段时间了。

希望对看到这里的你有所帮助。Enjoy It :-) (前端达人轻喷)

转载于:https://my.oschina.net/cevin15/blog/740368

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值