戏说Javascript

达芬奇密码2018-06-25 09:49

1. 类和原型

在学校中,我们一般学习的程序语言是C++或者是Java,他们都是原生支持类的,而Javascript没有原生支持类,而是通过原型来共享(属性或方法)。类和原型有什么区别呢?且听戏说之:

你是土豪(非常豪),想造个豪宅

  1. 你找贝聿铭设计了图纸,然后找王思聪他爹照着图纸造出你的豪宅,图纸就是类,造出来的豪宅就是这个类的一个对象。
  2. 你觉得找贝聿铭画图纸还不够土豪,你直接照着白宫,直接造了个山寨土豪版白宫,你山寨土豪版白宫是个对象,白宫也是个对象,白宫是你山寨土豪版白宫的原型。当然你可能觉得白宫还是不够豪,你把墙面全部贴金,再弄个自由女神像在院子里面做装饰,那么贴金和自由女神像就是你土豪山寨版白宫的自身属性。

2. 构造器、原型、实例

尽管Javascript中没有原生支持类,但是我们还是可以通过构造器(构造函数)来构造实例对象,如:

function Person(name, age){
    this.name = name;
    this.age = age;
}
var jerry = new Person('jerry', 1);

并且可以通过构造器(构造函数),来指定实例对象的原型,如:

Person.prototype.type = 'Human';
Person.prototype.introduce = function(){
    return "My name is " + this.name + ".I am " + this.age + " years old.";
};

那么Javascript中构造器、原型、实例又是什么关系呢?且听戏说之:

玛莎拉蒂的汽车生产线能够生成白富美喜爱的玛莎拉蒂跑车,每一辆玛莎拉蒂跑车都是实例对象,汽车生产线我们就可以认为是构造器对象,它能够生产实例对象的。我们可以认为能够生成实例对象的对象就是构造器对象。构造对象也有它自身的属性,比如生产线是 made in china 、生产线的大小等。

机器相对人类还是弱爆了,人类现在能够克隆人。比如你可以克隆一个林志玲,我们叫她林美玲,然后你想干嘛干嘛。那么林志玲就是林美玲的原型对象(因为林美玲是以林志玲作为模型克隆出来的)。然后你可以给林美玲戴朵花,穿个性感的衣服啊,花、性感衣服是林美玲这个实例对象的自身属性,不会影响到林志玲这个原型。当然因为中国人太多,房子太贵,克隆出来没地方住,林美玲只能持有一个到林志玲的专线电话(引用),通过这个专线电话林志玲随叫随到,这样除了花、性感衣服其他是不占地方的。

3. apply/call

在C++/Java这些面向对象的语言,一个对象要想调用另一个对象的方法,一般要对象的类继承另一个对象的类。而在Javascript中使用apply/call就可以轻松办到。 比如:

function Point(x, y){
    this.x = x;
    this.y = y;
}
Point.prototype.move = function(x, y){
    this.x += x;
    this.x += y;
};

var p = new Point(0, 0);
p.move(2, 3); // p -> {x:2, y:3}

var circle = {x:1, y:1, r:2};
p.move.apply(circle, [2, 3]); // circle -> {x: 3, y: 4, r:2}

C++/Java 没有apply/call不也过得很high,它们到底有啥用?下面我以apply为例,且听戏说之:

apply可以认为是借用,我先做一个比喻,然后在针对性的讲上面的代码。 比如我有个豆浆机可以打豆浆,你现在要开party要借我的豆浆机打豆浆,当然你必须先准备黄豆。 上文中的

p.move.apply(circle, [2,3])

对照这个比喻可以等价于:

我.用我的豆浆机打豆浆功能.借给(你,你的黄豆)

调用的结果就是做出了你的豆浆,party女王就喝到了你的豆浆了。

4. 正则表达式

正则表达式是一种表达字符串格式的表达式,主要用来匹配某类字符串,在各种语言都有实现。Javascript中常用 /某种格式/修饰符 来表示正则表达式。枯燥的教义之后,且听戏说之:

  1. 正则表达式 /phone/ 表示包含'phone'字符串,那么 /phone/.test('My phone number is 13111456788') 当然返回true, 因为 'My phone number is 13111456788'字符串中包含'phone'字符串。
  2. 现在我要把 'My phone number is 13111456788' 中的手机号码替换成 '就不告诉你' 我当然可以这么做 'My phone number is 13111456788' .replace(/13111456788/, '就不告诉你'); 当然返回 "My phone number is 就不告诉你"
  3. 对于一个有逼格的程序员,上面的实现方式明显太low了,如果字符串中出现的是其他手机号码而不是"13111456788",作为一个有逼格的程序员至少也要搞出能替换所有手机号码的程序嘛,于是我们需要一个牛B的东西叫做 字符类,故名思议它能表示一类字符,比如[0-9](字符类的语法是[字符类包含的字符])表示数字,使用字符类我们升级下逼格: 'My phone number is 13111456788' .replace(/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/, '就不告诉你');
  4. [0-9]有5个字符,写起来不爽,我们引入元字符,元字符是预定义的特殊字符,其中 \d 表示数字等价于[0-9],使用元字符我们再升级下逼格: 'My phone number is 13111456788' .replace(/\d\d\d\d\d\d\d\d\d\d\d/, '就不告诉你');
  5. 什么我们的代码中出现了11个\d, 码农教义第一条 Don't Repeat Yourself ,你都不知道嘛。为了进一步提升逼格,我们需要另个一牛B的东西叫做量词,顾名思义是表示数量,使用量词{11}(表示出现11次)我们又升级下逼格: 'My phone number is 13111456788' .replace(/\d{11}/, '就不告诉你');
  6. 假如我有两个电话号码,'My phone number is 13111456788 and 13563546782' 那么 'My phone number is 13111456788 and 13563546782' .replace(/\d{11}/, '就不告诉你'); 运行结果为: "My phone number is 就不告诉你 and 13563546782"。 啊,我想都不告诉你们,怎么还告诉你们 13563546782,我的粉丝不是要打爆我的电话了。这个时候我们需要另一个牛B的东西修饰符,我们使用 g (表示所有匹配的字符串),使用修饰符我们升级下逼格: 'My phone number is 13111456788 and 13563546782' .replace(/\d{11}/g, '就不告诉你');

以上我们把正则表达式最主要的特性,基本串起来的,正则表达式里面还有很多其他的字符类,元字符,量词,修饰符等。、

本文来自网易实践者社区,经作者魏文庆授权发布。