资讯专栏INFORMATION COLUMN

【阅读笔记】JavaScript语言精粹

cucumber / 3260人阅读

摘要:对之前看高级程序设计时没有注意到的一些知识点,结合本书做以补充语法注释源于的型既可以出现在字符串字面量中,也可能出现在正则表达式字面量中,如故一般建议使用型注释保留字语句变量参数属性名运算符和标记等标识符不允许使用保留字,此外在对象字面量中

对之前看《JavaScript高级程序设计》时没有注意到的一些知识点,结合本书做以补充

语法

注释

源于PL/I的/* */型既可以出现在字符串字面量中,也可能出现在正则表达式字面量中,如

/*
 var a = /a*/.match(s);
*/

故一般建议使用//型注释

保留字

语句、变量、参数、属性名、运算符标记标识符不允许使用保留字,此外在对象字面量中,或用点运算提取对象属性时,也都不能用保留字做属性名

数字

JavaScript只有一种数字类型,即64位浮点数

字符串

1.JavaScript中所有的字符都是16位
2.转义字符可以将反斜线引号,和控制字符等不被允许的字符插入到字符串中
3.u用来约定指定数字字符编码"A"==="u0041"
4.字符串一旦被创建就无法被改变,只能通过+等操作符创建新字符串

语句

1.JavaScript中的代码块{}不会创建新的作用域,故变量应该定义在函数的头部,而不是代码块中
2.被当做假的值false,null," ",0,NaN
3.JavaScript不允许在return关键字和表达式之间换行,也不允许在break关键字和标签之间换行

对象

定义

JavaCript中的对象是可变键控集合,是属性的容器,属性名可以是包括空字符串在内的任意字符串,属性值是除undefined值之外的任何值

对象字面量

一个对象字面量就是包围在一对花括号中的零个或多个名/值对,其中若 属性是合法的JavaScript标识符(字母开头,加数字、下划线组成)且不是保留字,则并不强制要求加引号

对象值得检索

属性名为非合法的JavaScript标识符,需用[]来读值,为合法的标识符且不是保留字,则也可以用.来读值,通常更倾向于.,因为其效率更高更紧凑,尝试从undefined的成员属性中读值会导致TypeError异常,如

flight.equipment // undefined
flight.equipment.model // throw "TypeErrpr"

引用

对象通过引用传递,不会被传递,换句话说var a = {}; b = a;b则和a指向同一块内存

原型

何为委托?沿原型链查找的过程就是委托(ps:原型链的末端是Object.prototype)

反射

获取对象上的属性而不要原型中的属性,使用hasOwnProperty()检查,若为对象实例上的属性,则会返回true

枚举

for in 可用来遍历一个对象上的所有属性名(包括实例和原型),但需注意的是for in遍历出来的属性是无序的

删除

delete无法删除原型中的属性

减少全局变量污染

措施:声明一个全局变量,作为命名空间,然后将应用资源都放到这个命名空间中,可以有效的减少与其他程序,组件,类库的冲突

函数

函数对象

Js中函数就是对象,连接到Function.prototype上,而Function.prototype则连接到Object.prototype

函数字面量

函数字面量包含以下4个部分:
保留字:function
函数名:可省略,此外函数还可以通过函数名来进行递归调用
形参:函数中的形参不会被如普通变量一样被初始化为undefined,而是在函数被调用的时候被初始化为实参所提供的值
语句:包围在花括号中的一组语句被称为函数的主体

调用

在一个函数中调用另一个函数,会暂停对当前函数的执行,并将控制权和参数传递给新函数,此外每个函数还会接收两个附加参数thisarguments(其中this的值取决于函数的调用模式)

函数的调用模式主要存在以下4种:
1.方法调用模式:函数被保存为一个对象的属性时,当此函数被调用时this即指向该对象
2.函数调用模式:当函数并非对象的属性,就被当做一个函数调用时,this会被绑定到全局对象上,但这种设计在实际开发中会造成很多的不便,因此我们常会再声明一个变量并将其赋值为this,如下:

var obj = {name:"aleen"};
obj.sayName = function(){
    var that = this;
    var say = function(){
        alert(that.name);
    }
    say();
}
obj.sayName();

3.构造器调用模式:使用new调用构造函数时,会创建一个连接到构造函数prototype成员的新对象,并将函数中的this绑定到新对象上
4.Apply调用模式:因为Js中的函数也是对象,所以函数也拥有方法,任何函数在调用时使用Apply方法,可以改变函数运行时this的运行对象(apply的第二个参数可传入一个参数数组)

var obj = {age:21};
var sayName = function(){alert(this.age)}
sayName.apply(obj);

参数

arguments:在函数内部可以通过该变量访问所有在函数运行时传递给函数的实参(包括没有被形参接收的参数),但是注意arguments只是一个类数组的对象,拥有length属性,但并没有任何数组方法

返回

一个函数总会返回一个值,如果没指定值,则返回undefined,注意当函数在调用时前面加上了new并且返回值不是一个对象,则返回新对象即this

异常处理

Js中可用throw来抛出异常

isNum = function(num){
    if(typeof num != "number"){
        throw {
            name:"type error",
            message:"there needs a number"
        }
    }
}

try{
 isNum("a");
}catch(e){
 document.writeln(e.name+";"+e.message);
}

扩充类型的功能

即使用prototype在原型上扩充实例可以共享的方法,但有一点需注意的是——基本类型的原型是公用结构,所以在类库混用时需小心使用,保险的做法是只在确定没有改方法时再添加它

递归

注意一些语言为尾递归提供了优化,可以显著提高速度,但Js并没有提供尾递归的优化,深度递归可能会因为堆栈溢出而运行失败
尾递归示例:

var factorial = function  factorial(i,a){
    a = a||1;
    if(i<2){
       return a;
    }
    return factorial(i-1,a*i);
};
console.log(factorial(4));

作用域

没有块级作用域(ES6中已有块级作用域了),故最好在函数顶部声明所有函数体中可能用到的变量

闭包

一个函数可以访问它被创建时的上下文环境,即成为闭包
此外:要避免在循环中创建函数

回调

回调函数是异步处理的,故不会因为网络传输或服务器响应慢而导致客户端出现假死状态

模块

简而言之:模块是一个提供接口却隐藏状态和实现的函数或对象
一般形式:定义一个拥有私有变量和特权函数(特权函数利用闭包特性可以访问私有变量)的函数,最后返回这个特权函数或者将其保存到一个可访问到的地方

级联

级联使得我们可以多带带在一条语句中依次调用同一个对象的很多方法

柯里化

简单来说,柯里化就是将函数与传递给它的参数相结合产生新的函数的过程

function add(a,b){
    return a+b;
}
Function.prototype.curry = function(){
    var slice = Array.prototype.slice,
    args = slice.apply(arguments),
    that = this;
    return function(){
        return that.apply(null,args.concat(slice.apply(arguments)));
    };
}
var add1 = add.curry(1);
console.log(add1(6));

记忆

例如斐波那契

var fibonacci = function(n){ 
    return n < 2 ? n : fibonacci(n-1)+fibonacci(n-1)
    }
    

频繁递归调用会消耗极大的资源,因此可以采用记忆策略,将已经计算过的值缓存起来

var fibonacci = function(){
    var meno = [0,1];
    var lib = function(n){
        var result = meno[n];
        if(typeof result !== "number"){
            result = fib(n-1)+fib(n-2);
            meno[n]=result;
        }
        return result;
    }
    return fib;
}();
数组

JavaScript中的数组是一种类似于数组的对象,它将数组的下标转变成字符串,并用其作为属性

数组字面量

数组字面量var num = [1,2,3];和对象字面量var num_obj = {"0":1,"1":2,"2",3}基本一致都是包含3个属性的对象,但它们的原型不同,num的原型是Array.prototypenum_obj的原型是Object.prototype,故 numlength属性而num_obj没有

ps:不同于强类型的语言,Js中的数组元素可以是不同类型的值

长度

1.Js中的length属性是没有上界的,当使用大于或等于length的位置来存储元素时,不会发生数组越界错误,而会自动增加length的值以容纳新元素

2.length属性的值不一定等于数组里的属性个数,如

myArray[100]=true;
myArray.length //101
//数组中只包含一个属性

3.[]下标运算符会将所含表达式转换为一个字符串,当表达式有`toString方法时,就使用该方法的值

4.JavaScript中的数组下标必须是大于等于0并小于等于2的32次方-1的整数

5.设置更大的length不会给数组分配更多的空间,而把length设小将会导致所有下标大于等于新length的属性会被删除

删除

因为数组也是对象,所以可以用delete来删除数组中的元素,但它只会将那块的值移除掉,而保留那块的空间,故那块的值就变成undefined了,因此常用splice方法来删除元素,但此方法的特点在 删除元素时是将被删除的元素之后的元素全部移除,再不断添加到新位置,这种做法对于大型数组来说效率不高

枚举

数组可用for in来枚举元素,但它不会保证数组元素的顺序,因此我们常用在枚举时我们常用for循环

数组和对象的判断

由于在Js中,数组和对象极易混淆,所以一个较好的判断其类型的方法是:

var is_Array = function (value){
    return Object.prototype.toString.apply(value).slice(8,-1) === "Array";
}

指定初始值

Js不会给数组元素预设初值,[]得到的新数组为空,访问一个不存在的元素则是undefined

代码风格

1.代码块内容和对象字面量缩进4个空格
2.if和()之间放置一个空格
3.每个逗号和冒号后面都使用一个空格
4.在if和while这样的结构化语句里,始终使用代码块
5.将{放在一行的结尾,而不是第二行的开头
6.尽量使程序具备自我说明,并添加必要注释,推荐行注释
7.尽量在每个函数开始的地方,声明所有变量
8.避免switch语句块的条件穿越到下一条case

优美的特性 毒瘤

全局变量

代码块中没有块级作用域

自动插入分号,故应该在将{放在上一行的尾部,而不是下一行的头部

保留字,Js中的保留字不能用来做变量名和参数,当保留字被用作对象字面量的键值时,必须用""括起来,并用[]引用

糟粕

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83595.html

相关文章

  • javascript语言精粹》学习笔记 - 继承

    摘要:但采用构造器调用模式,即是使用了前缀去调用一个函数时,函数执行的方式会改变。对象包含构造器需要构造一个新的实例的所有信息。构造器的变量和内部函数变成了该实例的私有成员。 JavaScript 是一门弱类型语言,从不需要类型转换。对象继承关系变得无关紧要。对于一个对象来说重要的时它能够做什么,而不是它从哪里来。 阅读《javascript语言精粹》笔记! 伪类 js的原型存...

    harriszh 评论0 收藏0
  • 阅读笔记javascript 语言精粹

    摘要:前言由于最近的项目用到了一些的代码,所以我带着好奇心,认真阅读了这本书,粗略地了解语言的基本结构和特性,对于一些不熟悉的新概念,以记录的形式加强印象,也是对学习的反思总结。 前言 由于最近的项目用到了一些js的代码,所以我带着好奇心,认真阅读了这本书,粗略地了解js语言的基本结构和特性,对于一些不熟悉的新概念,以记录的形式加强印象,也是对学习的反思总结。 一、字面量(literals...

    tangr206 评论0 收藏0
  • javascript语言精粹》学习笔记 - 对象

    摘要:对象适用于汇集和管理数据。一个对象字面量就是包围在一对花括号的多个名值对。尝试从对象里取值将会导致异常。亦不会触及原型链中的任何对象。严格模式下,不能用删除显式声明的标识符,名称或具名函数。 Javascirpt里的对象是无类型的。它对新属性的名字和属性的值没有任何的限制。对象适用于汇集和管理数据。对象可以包括其他对象,所以它们可以容易地表示成树状或者图形结构。 对象字面量 ...

    LoftySoul 评论0 收藏0
  • javascript语言精粹》学习笔记 - 数组方法实现

    摘要:在中数组是经常被使用到的,我们除了要学习数组的方法,还需要了解诶一下某一些方法是如何来实现的。然而我看了语言精粹中方法的一章,想记录下书上的代码,以便加深印象。方法移除数组中的第一个元素并且放回该元素。 在js中数组是经常被使用到的,我们除了要学习数组的方法,还需要了解诶一下某一些方法是如何来实现的。然而我看了《javascript语言精粹》中方法的一章,想记录下书上的代码,以便加深印...

    felix0913 评论0 收藏0
  • JavaScript 语言精粹》读书笔记 - 函数

    摘要:语言精粹读书笔记第四章函数函数字面量函数字面量包含个部分第一部分,保留字第二部分,函数名,它可以被忽略。这个超级延迟绑定使得函数对高度复用。构造器调用模式一个函数,如果创建的目的就是希望结合的前缀来调用,那它就被称为构造器构造。 《JavaScript 语言精粹》 读书笔记 第四章 函数 Functions 函数字面量 函数字面量包含4个部分: 第一部分, 保留字 function...

    wdzgege 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<