资讯专栏INFORMATION COLUMN

Effective JavaScript读书笔记(一)

zhoutao / 949人阅读

摘要:如果为假值,不传或者传入,函数都会返回但是,传入这个值是完全有可能的,所以这种判断形势是不正确的或者使用来判断也可以原始类型优于封装类型对象拥有六个原始值基本类型布尔值,数字,字符串,,和对象。

作为一个前端新人,多读书读好书,夯实基础是十分重要的,正如盖楼房一样,底层稳固了,才能越垒越高。从开始学习到现在,基础的读了红宝书《JavaScript高级程序设计》,犀牛书《JavaScript权威指南》,特别是红宝书,是把我领进js领域的一本书。现在到了进阶阶段(可能红宝书还会回去继续翻),准备开始读《Effective JavaScript》,刚拿到手,很薄的一本书,也把读书笔记整理下来,希望养成一个良好的读书习惯。

让自己习惯JavaScript 了解JavaScript的版本

目前主流JavaScript版本任然是ES5,在ES5开始引入严格模式

use strict;//在文件头或者函数体顶部使用,就是严格模式

一般来说,我们如果想编写一个通用型插件,都需要使用严格模式来进行开发,但是在使用严格模式开发时会出现一个问题,工程先后引入两个文件file1.js和file2.js,file1.js使用的严格模式进行开发,file2是非严格模式,那么下面的代码会出问题。

真值运算
JavaScript中的逻辑运算if、||和&&理论上是可以接受任何值的,因为JavaScript中
所有类型都会在逻辑运算中转换成布尔值

JavaScript中有7个假值:false、0,-0、""、NaN、null、undefined

由于数字和字符串可能为假值,所以,使用针织运算检查函数参数或者对象属性是否已经存在不是绝对安全的。

function point(x){
    if(!x){
        return 26;//如果x为假值,不传或者传入0,函数都会返回26
    }
}
point(0);//x:26
//但是,传入0这个值是完全有可能的,所以这种判断形势是不正确的
function point(x){
    if(typeof x === "undefined"){
        return 26;
    }
    //或者使用if(x === undefined)来判断也可以
}

原始类型优于封装类型

JavaScript对象拥有六个原始值基本类型: 布尔值,数字,字符串,null,undefined和对象。

需要注意的是,使用typeof对null判断得到的结果是"object",ECMAScript标准描述null是一个独特的类型

创建原始类型与创建基本类型
//创建一个String对象,内部封装一个字符串值
var s = new String("hello");
s + " world";// "hello world"
//创建一个原始类型
var str = "string";
//封装类型本质是一个对象,原始类型才是基本类型,可以使用typeof来查看
typeof s;// "object"
typeof str;// "string"
//由于封装类型自身是一个对象,因此即使内部封装的值相同,两个对象也是不相等的
var s1 = new String("string");
var s2 = new String("string");
s1 === s2;//false
s1 == s2;//false

总体来讲,一般不需要使用封装类型来代替基本类型,因为基本类型无论是从声明还是使用都较为方便。而且,基本类型本身是没有任何方法的,不过可以隐式转换成String对象来执行其内部方法:

var s = "hello";//基本类型
s.toUpperCase();//HELLO,将s隐式转换成String对象

【注】隐式封装的类型有一点需要特别注意:每一次隐式封装都会产生一个新的String对象,原来的对象会被抛弃,也就是说新产生的隐式封装对象生命周期就是所在行代码执行完成。

"string".value = 26;
"string".value;//undefined
第二行代码隐式封装形成了新的String对象,新的String对象内部没有value这个属性值,因此是undefined

对JavaScript原始类型值设置属性是没有意义的

避免对回合类型使用 == 运算符

由于JavaScript隐式转换的存在,因此,在使用 == 运算符的时候,有时候可能不会得到我们所预期的结果。

"1.0e0" == { valueOf: function(){ return true } };
//结果是true,因为右侧valueOf结果是true,会被隐式转换成数字1,根据隐式转换法则,左侧字符串也会被隐式转换成1,因此比较是相等的。
// 使用==运算符比较时一些特殊情况
null == undefined;//true,这种情况永远是true
null/undefined ==
string/number/boolean;//false,这种情况永远是false
string/number/boolean == string/number/boolean;// 将原始类型转换为数字进行比较
string/number/boolean == Date对象;// 先将原始类型转化成数字,再将date类型转化成原始类型(优先尝试toString,其次尝试valueOf)
string/number/boolean == 非Date对象;// 先将原始类型转化成数字,再将date类型转化成原始类型(优先尝试valueOf,其次尝试toString)

// 关于Date对象比较问题

var date = new Date("1993/07/11");
date == "1993/07/11";//false

这是因为Date对象调用toString方法之后转换的不是我们所熟知的字符串形式。

在浏览器中调用date.toString(),结果是"Sun Jul 11 1993 00:00:00 GMT+0800 (中国标准时间)"

//将Date类型字符串转换成我们定义格式的字符串
function toYMD(date){
    var y = date.getYear() + 1,
        m = date.getMonth() + 1,
        d = date.getDate();
    return y + "/"
         + (m < 10 ? "0" + m : m) + "/"
         + (d < 10 ? "0" + d : d);
}
toYMD(new Date("1993/07/11")); //"1993/07/11"

在比较的时候,最好使用严格相等运算符 ===,这是一个良好的习惯

了解分号插入的局限

JavaScript语法对于分号没有硬性的规定,其语言机制自身会自动添加分号而区分开语句,了解分号插入的规则,对于提高JavaScript代码的严谨性有着巨大的帮助。

分好仅在 } 标记之前、一个或多个换行符之后和程序的输入结尾被插入

换而言之,我们只可以在一行、一个代码块和一段程序结束的地方省略分号,其他任何地方省略分好都有可能出现错误。

function foo1(r){ r += r; return r };//合法
function foo2(r){ r += r return r };//不合法
分好仅在随后的输入标记不能被解析时插入

换句话说,分好是JavaScript为我们提供的一种错误校正机制

a = b
(f());
// 上面这段代码会被解析成
a = b(f());//这是一条合法语句
a = b
f();//下面这段代码会被解析成两条独立的语句,因为 a = b f()是不合法的语句

换句话说,其实JavaScript只是为我们机械化的解决了语法问题而已,如果解析不合法,就会为我们通过插入分号来解决问题,但是,可能不是我们所预期的,因此,规范化的代码才是重中之重,尽量不要省略分号。

另一个比较重要的情况是:return语句,在return关键字和其可选参数之间一定不可以包含换行符。

return {}; //一条语句,返回一个空对象
return 
{}; 
//上面语句等价于
return ; 
{}
;
也就是会自动在return后面的换行符前插入一个分号

另外一种特殊情况就是++运算符和--运算符

a
++
b;
//会被解析成
a;
++b;

在return、throw、break、continue、++、--的参数之前不可以换行

分号不会作为分隔符在for循环空语句的头部被自动插入

也就是说,for循环体内必须显式的包含分号,否则会出错

for(var i = 0, total = 1 // 解析出错
    i < n
    i++)
视字符串为16位的代码单元序列

几种流行的Unicode编码:utf-8、utf-16、utf-32

JavaScript字符串是由16位代码单元组成,而不是由Unicode代码点组成

JavaScript使用两个代码单元表示2e16及以上的Unicode代码点。这两个代码单元被称为代码对。

代理对甩开了字符串元素计数,length、charAt、charCodeAt方法以及正则表达式模式受到了影响

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

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

相关文章

  • Effective JavaScript读书笔记(二)

    摘要:尽可能的使用局部变量,少用全局变量。正确的实现就是在函数体内部使用将声明成局部变量。在新特性中,引入了块级作用域这个概念,因此还可以使用,来声明局部变量。它们共享外部变量,并且闭包还可以更新的值。 变量作用域 作用域,对于JavaScript语言来说无处不在,变量作用域,函数作用域(运行时上下文和定义时上下文),作用域污染等等都跟作用域息息相关,掌握JavaScript作用于规则,可以...

    Yuqi 评论0 收藏0
  • 读书笔记:编写高质量javascript的68个方法

    摘要:第条尽量少使用全局对象避免声明全局变量尽量声明局部变量避免对全局变量增加属性第条始终声明局部变量第条避免使用语句第条熟练使用闭包的函数值包含了比调用他们时执行所需要的代码还要更多的信息。那些在其所涵盖的作用域内跟踪变量的函数称为闭包。 书还没看完。一遍看,一遍写读书笔记。 这本书的序是JavaScript之父Brendan Eich写的,作者是JavaScript标准化委员会专家。可想...

    Vicky 评论0 收藏0
  • JavaScript模式》读书笔记:基本技巧

    摘要:模式的读书笔记,个人向更新进度随我的阅读进度基本技巧尽量少用全局变量防止变量污染注意变量提升问题尽量使用单一模式,只使用一个在函数顶部进行变量声明函数体循环优化循环条件优化对进行操作上面那种循环,将作为循环条件,每次循环时都要访问数据的长度 《JavaScript模式》的读书笔记,个人向!更新进度随我的阅读进度 基本技巧 尽量少用全局变量 防止变量污染 注意JS变量提升问题 尽量使用...

    wapeyang 评论0 收藏0

发表评论

0条评论

zhoutao

|高级讲师

TA的文章

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