JavaScript 程序设计——进阶篇

1.类型进阶

类型

原始(值)类型:Undefined Null Boolean String Number Object

对象(引用)类型:Object

通过 JS 语言操作的所有东西几乎都是 Object 类型的对象。

对象类型:分为浏览器扩展对象,宿主对象和原生对象。原生对象分为构造函数和对象。

构造函数:Boolean String Number Object Function Array Date RegExp Error

对象:Math JSON 全局对象 arguments

原始类型和对象类型的区别

所有的原始类型的值存在栈内存中,可直接用变量标识符取到它的值并为它赋值。

对象类型的栈内存中只存储地址,实际的值存储在堆内存中,地址指向堆内存中的值。对象类型赋值时仅赋予地址值。

隐式类型转换

JS 是一门弱类型语言,表示语言本身会做一系列的隐式类型转换。

数学运算符

+ 操作:一端是字符串,一端是数字时,数字被隐式转换为字符串,实现字符串连接操作。

其他数学运算符:一端是字符串,一端是数字时,字符串被隐式转换为数字进行数值计算。

 . 操作:所有的直接量用 “.” 调用某个方法时,JS 运行环境会将直接量转换为对应的对象类型,调用对象类型上的方法实现功能。

if 语句:条件部分的表达式结果隐式转换为布尔值进行判别。

==:在做 == 操作时会进行隐式类型转换。

显式类型转换

在隐式类型转化不满足需求时,需要进行显式类型转换。

Number()  String()  Boolean()

parseInt() parseFloat()   字符串转换为数字

! !! 取得操作对象的布尔值

类型识别

typeof:可以识别标准类型(Null 除外),不能识别具体的对象类型(function除外)。

instanceof:判别内置对象类型,自定义对象类型(及父子类型)。不能判别标准类型。

Object.prototype.toString.call():可以识别标准类型以及内置对象类型,不能识别自定义类型。

constructor:识别标准类型(null,unefined 除外),内置对象类型,自定义类型。


2.函数进阶

函数定义:函数声明,函数表达式,函数实例化。

函数声明定义函数的特点:函数定义会被前置;重复定义函数时,最后一次定义有效。

函数实例化定义函数的特点:定义的函数只能访问本地作用域和全局作用域。

JS 代码执行过程:在 JS 代码执行之前,JS 引擎首先会对需要执行的 JS 代码做一次预解析,将一些变量声明,函数定义提前处理,然后再单步执行 JS 代码。

函数调用

函数调用模式:add(1);

方法调用模式(函数作为对象属性):myNumber.add(1);

构造函数调用模式:new Function(...);

apply(call) 调用模式:为Function构造函数原型链中一个方法,实现函数调用功能,将函数借用给一个对象,帮助它实现函数所定义的逻辑。

Function.prototype.apply()的使用

函数执行时,JS 引擎会在函数自己的本地作用域上自动添加 this,arguments 这两个临时变量,调用模式的区别体现在 this 变量的指向上。

函数调用模式的区别——this:

函数调用模式:this 指向全局对象

方法调用模式:this 指向调用者

构造函数调用模式:this 指向被构造的对象

apply(call)调用模式:this 指向第一个参数(借用方法的对象)

arguments:用于获取函数实参的对象,类似数组的对象。arguments[index] 获取实参,arguments.length 获取函数实参个数。

函数传参

按值传递(call by value):一个外部变量传递给一个函数时,函数实参获取到的是外部变量的一个副本,在函数内部对实参进行的修改不会反映到外部变量上。

按引用传递(call by reference):一个外部变量传递给一个函数时,函数实参是外部变量的一个引用,在函数内部对实参的任何修改都会反映到外部变量上。

按共享传递(call by sharing):一个外部变量传递给一个函数时,函数实参获取到的是外部变量的一个副本,在函数内部对实参进行赋值不会反映到外部变量上,修改实参对象的属性值,会反映到外部变量上。

原始类型按值传递,对象类型按共享传递。

闭包

函数内部的子函数用到了父函数的变量形成的特定作用域。

功能:保存函数的执行状态,封装,性能优化。

保存函数的执行状态
封装,隐藏status,light对象属性
性能优化:函数在闭包作用域内,减少函数定义时间和内存消耗

first-class function

JS 当中的函数可以被当作普通变量所使用,可被当作参数,也可被当作返回值返回。

功能:函数作为参数(异步回调函数);函数作为参数(curry)

函数柯里化通常是指把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的并且返回一个接受余下的参数而且返回结果的新函数的技术。

更泛化的定义是指给函数分步传递参数,每次函数接受部分参数后应用这些参数,并返回一个函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数的函数,直至返回最后结果。归纳一下就是逐步传参,逐步缩小函数的适用范围,逐步求解的过程。

从更上层的角度去理解,柯里化允许和鼓励你将一个复杂过程分割成一个个更小的更容易分析的过程(这些小的逻辑单元将更容易被理解和测试),最后这样一个难于理解复杂的过程将变成一个个小的逻辑简单的过程的组合。

function.prototype.bind

bind 返回的是一个函数引用,而不执行。调用函数引用才执行绑定的函数。

3.原型

原型 vs 类

类构造对象的方式是一个从抽象到具体的过程(new 关键字构造),类是具体事物的抽象,对象是具体的。

原型构造对象的方式是从具体到具体的过程。使用现有的对象去构造一个新的对象。

原型构造对象方式:Object.create 构造函数

Object.creat(proto):proto 为一个对象,作为新创建对象的原型。

var landWind = Object.create(landRover);

被创建的对象有一个内置属性 _proto_,指向对象的原型。

构造函数:使用 prototype 设置原型,使用 new 创建对象。

每个函数有 prototype 属性,为一个指针,指向一个原型对象(通过该构造函数创建实例对象的原型对象)。实例 ——> 原型对象 <—— 构造函数

new 的过程拆分为三步:创建对象;设置被创建对象的 _proto_ 指向原型对象;apply 实现函数借用功能。

原型链

网页截图

网页

对象属性的访问:优先在对象本身查找,对象本身定义顺着原型链查找。

对象属性的修改,删除:只能修改,删除对象自身的属性,不影响其他对象。

JS 里所有对象,背后都有原型链存在。

对象.hasOwnProperty(属性) 判断传入属性是不是对象自身的属性,是返回 true,否则返回 false。


4.变量作用域

JS 使用静态作用域。由程序定义的位置决定。在编译阶段决定,与代码执行顺序无关。一般采用嵌套作用域的规则解析。

JS 没有块级作用域(全局作用域,函数作用域)

使用词法环境管理静态作用域

词法环境

描述环境的对象,包含环境记录(环境里定义的形参、函数声明、变量。),对外部词法环境的引用(outer)。

一段JS代码执行之前,会对环境记录进行初始化(声明提前),即将函数的形参、函数声明和变量先放入函数的环境记录中,特别需要注意的是:形参会在初始化的时候定义值,但是函数内部定义的变量只声明不定义(不赋值)。

词法环境——with,try-catch 函数

以 with 为例,在 JS 里面会创造一个临时的词法环境,传入的参数定义到 with 的环境记录中。但在 with 中定义的变量,函数声明为全局作用域。匿名函数的 outer 指向 with 词法环境。

函数表达式和函数声明的作用域

函数表达式在执行时改变作用域,函数声明只与定义时的位置有关。

带名称的函数表达式作用域

执行时创建新的词法环境,不会定义到全局。名称不能修改。


5.闭包

闭包由函数及其相关的引用环境的组合而成。

闭包允许函数访问其引用环境中的变量(又称自由变量)。

广义上来说,所有 JS 的函数都可以成为闭包,因为 JS 函数在创建时保存了当前的词法环境。

闭包的应用:保存现场,封装


6.面向对象

全局变量:可以在程序的任何地方访问。

var test = 'some value'; 无法用 delete 删除

window.test = ‘some value’;

(function(){var a; test = 'some value';})(); 写了变量赋值但未用 var 定义。

后两种方法将变量定义在 window 对象上面,可使用 delete 删除。

封装形式

私有的方法和属性供对象本身调用

继承

类继承和原型继承

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

推荐阅读更多精彩内容

  • 1,javascript 基础知识 Array对象 Array对象属性 Arrray对象方法 Date对象 Dat...
    Yuann阅读 899评论 0 1
  • 第5章 引用类型 引用类型的值(对象)是引用类型的一个示例。在ECMAScript 中,引用类型是一种数据结构,用...
    力气强阅读 714评论 0 0
  • 继承 一、混入式继承 二、原型继承 利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承,这种实现继承的...
    magic_pill阅读 1,054评论 0 3
  • 这几天宝宝压得我喘气又加重了,稍微运动一下呼吸频率和心跳就会明显增加。 耻骨联合痛也在使我行动变得困难和疼痛,不知...
    潇潇竹风阅读 141评论 0 0
  • 生如夏花之绚烂,死如秋叶之静美
    向晚生香阅读 88评论 0 0