Javascript 面向对象编程特训 - 1

Javascript 特训-1

本科时被一个笑话笑的肚子疼,问哪一句话会立即在互联网论坛里掀起腥风血雨。

答:PHP 是全世界最好用的语言

怎么会是 PHP 呢,一定是 Javascript,即可前端,也可服务器。

玩笑归玩笑。我个人最喜欢的语言是 Javascript,不是我真觉得它有多好,而是我最熟悉的就是它了,爱一行才能干一行嘛。因为最近用 Framer 做前端动效,发现制作难的效果需要更深层的理解面向对象编程。而 Framer 的代码是 Coffeescript, Coffeescript 又是由 Javascript 改编而来的。所以决定啃下 JS 面向对象编程这块硬骨头,向自己从前的面向过程编程说 Bye Bye.

正题,我是看 Udacity 的视频教程学习的,文末有视频链接,部分内容包涵个人理解,理解有误之处还请指正。

Scope

JS 的作用域有两种,第一种是全局作用域 Global,第二种是函数作用域 Function. 全局作用域在代码执行过程中一直存在,函数作用域在函数执行完之后消亡。

二者在层级关系上有着嵌套的关系,Global 嵌套着 Function,当代码执行时,从最底层 Scope 逐层往上搜寻变量。

嵌套关系

Closures

闭包,我的理解是,在 Function 执行后,依然能够调用 Function 中的变量。即局部作用域的内容再执行后,没有被销毁,依然可以被调用。

有 2 种方式可以实现闭包:

1.return

function Car(){
  var price = 3000;
    return function(){
      return price;   
  };
}
var obj = Car();
# Car 函数中的 price 仍然被调用了,没有被销毁
console.log(obj());

2.将其赋值给全局变量

var obj =[];
function Car(){
  var price = 3000;
  obj.push(price);
}
Car();
# Car 函数中的 price 仍然被调用了,没有被销毁
console.log(obj[0]);

This

JS 的 this 变量以前一直让我很困惑,不是很清楚怎么使用。今天终于弄清楚了,个人总结的一句话是

this 指向的是代码执行时的执行环境

比如:

var method = 2;
var obj = {
  method: 1,
  outputMethod: function(){
    console.log(this.method);
  }
}
# 输出的结果是 1
obj.outputMethod();

简单的说,this 指向的是.左边的对象,如果.左边为空,则指向 Global. 有一个例外,就是 new, new 会创建一个完全新的对象,this 指向该全新的对象,并返回该对象。如下:

var Car = function(p1){
  # this = Object.create();
  this.p1 = p1;
  # return this;
}
# this 指向 Car 类的实例 ford
var ford = new Car('1');

Prototype chains

原型链是 JS 一个很有特色的机制,一个对象可以引用其上层对象的属性和方法。这样可以让把重复的内容写在同一个 prototype 里面,节省存储空间。

var man = {gender: 'male'}
# boy 可以引用 man 的属性
var boy = Object.create(man);
# man 的上层对象是 Object, 因此还可以调用其 toString() 方法
boy.toString();

Object decorator pattern

写代码注意其可复用性,尽量写完代码后,审查一下是否可以有优化的空间,将相同的代码提取并合并,方便以后修改。

var man1 = {age:0};
man1.age++;
var man2 = {age:0}
man2.age++;

# man 作为一个有 age 的对象,可以提取出来。其次,age++ 这个操作可以提出出来单独成为一个函数。上述代码可以转成如下。

var man = function(obj, age){
  var obj = obj;
  obj.age = age;
  obj.agePlus = function(){
    obj.age++;
  }
  return obj;
}

var man1 = man({}, 0);
man1.agePlus();
var man2 = man({}, 0);
man2.agePlus();

代码量小的时候,可能看不出来优势。但是当代码量大的,提升的效率是几何级的了。设计师可以把这种提取看作是 Symbol 控件的整合。当你需要把页面中的 100 个相同按钮改变样式的时候,没有定义 Symbol 的你可能眼角会流下泪水吧。

Functional classes

JS 中,在我理解,所有内容本质上对象,这样一来,函数本身也是对象。因此可以把具有特性的函数进一步优化,成为具有一个特定功能的类,Class.

# 类首字母一般大写
var Man = function(age){
  var obj = {age: age};
  obj.agePlus = function(){
    obj.age++;
  }
  return obj;
}

var man1 = man(0);
man1.agePlus();
var man2 = man(0);
man2.agePlus();

此时 Man 函数就成了一个类,具有 age 属性。当然你可以扩展它,让其拥有更多的属性和方法。

Prototypal classes

由于很多人使用函数来定义类,为了优化人们的操作,JS 官方给了 new 方法,用于省去人们创建对象,会返回对象的操作。

# 类首字母一般大写
var Man = function(age){
# 不需要了
#  var obj = {age: age};
# this 指向的 Man 每次创建的实例 instance
  this.obj = obj;
  obj.agePlus = function(){
    obj.age++;
  }
# 不需要了
#  return obj;
}

var man1 = new man(0);
man1.agePlus();
var man2 = new man(0);
man2.agePlus();

Pseudoclassical patterns

伪类模式提出了 Prototype 的概念,起用于存储公共方法,节省内存空间,也是 JS 一个特性,也便于对 JS 类的扩展。

为了减少用户的工作量,JS 定义了 prototype, 用于存储这里 Car.methods. 我的理解是,把 prototype 想成一个单独的对象,类通过 prototype 调用其方法,prototype 通过 constructor 查询其构造函数。二者没有代理关系。但是通过 Class 创建的 instance 和 prototype 是代理关系,并可以直接调用其方法。

# Function 版本

var Car = function(price){
  # obj 继承了 Car.methods 的所有方法
  var obj = Object.create(Car.method);
  this.price = price;
  return obj;
}

# 定义公共方法
var Car.methods = {
  showPrice: function(){
    console.log(this.price);
  }
}

var ford = new Car(1);
ford.showPrice();

# 下面是 prototype 版本

var Car = function(price){
# 不用了
#  var obj = Object.create(Car.method);
  this.price = price;
# 不用了
#  return obj;
}

# 定义公共方法
var Car.prototype.methods = {
  showPrice: function(){
    console.log(this.price);
  }
}

var ford = new Car(1);
ford.showPrice();

Pseudoclassical subclasses

有的时候人们会想定义几个具有功能属性的类,但是又不想重复类之间的属性。这时便有了父类,子类,继承的编码思想出现了。好比,喜羊羊和灰太狼都是动物,它们有公共的属性,可以设置在父类里,还可以添加一个共有的显示价格方法, 但是它们也有各自独特的属性。

# 定义父类
var Animal = function(price){
  this.type = 'animal';
  this.price = price;
}
# 定义父类方法
Animal.prototype.showPrice = function(){
  console.log(this.price);
}
#定义子类

# 继承父类的属性, 同时继承父类的属性
var Chicken = function(price, wings){
# call()函数将 Animal.price 的执行环境改成 this, 由于 this 指向 Chicken 的实例,
# 因此 Chicken 实例就继承了 Animal 的属性
  Animal.call(this, price);
# 定义子类属性,鸡是有翅膀的
  wings = true;
}
# 继承父类的方法
# 把 Chicken.prototype 指向 Animal.prototype
# 从而 Chicken 的实例可以调用 Animal.prototype 的方法,真的膜拜 JS 发明人
Chicken.prototype = Object.create(Animal.prototype);

var chicken1 = new Chicken(10)
chicken1.showPrice();

总结

明确这些概念,以及这些概念背后的原因,对我下一步的学习有着很大的裨益。以前我觉得我看不懂的东西,耐心的思考一下,是可以看懂的。世上无难事,只怕有心人嘛。

下一步打算把教程后面的游戏 Project 给完成,用实战再次强化自己编程能力,最后用 Framer 把游戏再转到 Framer 平台上。自己画图,把游戏界面再做漂亮点。

希望一起练习的同学请和我联系,共同进步。

Reference

课程资源:https://classroom.udacity.com/courses/ud015

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,717评论 2 17
  • 0 写在前面的话 大多数的面向对象编程语言中,比如C++和Java,在使用他们完成任务之前,必须创建类(class...
    自度君阅读 987评论 0 3
  • 学习JavaScript语言的过程中“面向对象”的概念绝对是一道坎。JS没有“类”这个概念,因此要用它来进行面向对...
    Leesper阅读 604评论 0 1
  • ▼ 之前看的罗伊·马丁纳《改变,从心开始》书中说的一句话说到心坎儿上了。 “为了在心灵上有所成长,我们每个人都需要...
    白卷儿阅读 1,178评论 2 13
  • 前天我们讨论了本专业里让我们佩服的女生和男生,女生没有,男生有一两个。我们一致认为有些人注定就是做大事的,...
    牛犊与苏格拉底阅读 166评论 0 0