适合人群:初次上手JS的小白
文章目的:提炼书中重点的知识点,及部分tricky的特性,抛砖引玉,提高效率,具体内容还需要各位童鞋深入学习。
打分:9/10
为什么去看这本书?
项目中用的到。之前仅仅对Python与C,C++有系统学习,对JS不了解。从零开始上手。
以下为摘要的重点:
第一章:精华
1.JS是一门弱类型的语言,所以JS编译器不能检测出类型错误。这可能让从强类型语言转向JS的开发人员感到恐慌。(学C, C++ ,JAVA 入门的童鞋会有很深的共鸣)
2.所有编译单元的所有顶级变量被撮合到一个被称为全局变量的公共命名空间中,全局变量是魔鬼。但这却是JS必不可缺的一种特性。
第二章:语法
1.注释优先使用//而不是 /* ... */原因如下:
/*
var rm_a = /a*/.match(s);
*/
上面的注释中,内容包含 */,会导致一个语法错误。
2.JS只有一个数字类型,它在内部被表示为64位浮点数。
3.JS中只有以下值被当作为假: false , null , '' , 0 , NaN
第三章:对象
var flight = {
airline: "China East",
number: 815,
depature:{
IATA:"syd",
city:"sydney"
}
}
以上面这个对象为例:
1.选择对象内的属性,优先使用.而不是[],因为这样更紧凑且可读性更好。例如:
flight.airline
2.尝试从undefined的成员属性中取值将会导致TypeError异常。
flight.name//并不存在
3.对象通过引用来传递。它们永远不会被复制。
var x = flight
x.airline = 'Chun Qiu'
//因为x和flight指向同i个对象,所以x.airline = flight.airline = 'Chun Qiu'
4.如果一个对象中不存在某个属性,那么JS会试着从原型对象中获取属性值。如果原型对象也没有该属性,那么再从它的原型中寻找,依此类推。直到找到最终的object.prototype.
var f = function(){};
f.prototype = flight;
//此时访问f.airline 这个属性,它无法在f中找到airline ,JS会找到它的原型,即flight,则f.airline = ‘Chun Qiu’
f.airline = 'China South'
//此时访问f.airline,则f.airline = 'China South' , fight.airline = ‘Chun Qiu’
5.JS中的 for in 语法,属性名出现的顺序时不确定的。
6.删除对象的属性可能会让来自原型中的属性透现出来。
delete f.airline
//此时f.airline属性缺失,即'China South'这个值被删除。但如果再次访问f.airline,不会得到undefind,而是其原型的值,即‘Chun Qiu’
7.严格控制全局变量的数量。把全局变量放到一个list中。
var MYAPP = {};
MYAPP.flight = {
airline: "China East",
number: 815,
depature:{
IATA:"syd",
city:"sydney"
}
}
MYAPP.anotherParams = {
...
...
}
...
这样可以减小全局变量的污染。
第四章:函数
1.每个函数在创建时会附加两个隐藏属性:函数的上下文和实现函数行为的代码。
2.匿名函数:
var add = function(a, b){
return a + b
}
3.函数可以被定义在其他函数中,一个内部函数除了可以访问自己的参数和变量,同事它也能自由访问把它嵌套在其中的父函数的参数与变量。
4.当实际参数(args)的个数与形式参数(params)的个数不匹配时,不会导致运行时错误,如果实际参数多了,超出的参数会被忽略,如果实际参数少了,缺失的值会被替换为undefined.
5.当一个函数被保存为对象的一个属性时,我们称它为一个方法。
var myobject = {
value: 0 ,
incremnet: function (inc){
this.value += typeof inc === 'number'? inc : 1
}
};
myobject .incremnet();
//increment 方法。 判断入口参数是否是一个数字,是的话就进行加法运算。
方法可以用this访问自己所属的对象。这个例子中的value就是通过这种方式获取的。
this对象的绑定时发生在调用的时候,(这个概念非常重要,对increment这个方法而言,这个value不是在初始化的过程中已经获取的,而是在每一次的调用方法时,重新获得该值)这是一种“超级”延时绑定。
6.Apply调用模式:
//创建一个对象,拥有status属性。
var Quo = function(string){
this.status = string;
}
//给Quo的所有实例提供一个名为get_status的公共方法。
Quo.prototype.get_status = function () {
return this.status
}
//构造一个包含status的对象。
var statusobject = {
status: 'A-OK'
}
//statusobject 没有继承 Quo.prototype,但我们可以在 statusobject 上调用get_status 方法。
var status = Quo.prototype.get_status.apply(statusobject)
//如何理解:等于把statusobject对象中的status作为入口参数赋给get_status使用。
7.当函数被调用时,会得到一个“免费”配送的参数,那就是arguments数组。
arguments 并不是一个真正的数组。
var sum = function () {
var i , sum = 0;
for( i = 0 ; i < arguments.length; i += 1){
sum += arguments[i]
}
}
sum(1 , 2 , 3 , 4 , 5) //15
8.一个函数总有一个返回值,若没有指定,则返回underfined.
9.JS没有提供尾递归优化功能,深度递归的函数可能会因为堆栈溢出而运行失败。
10.闭包,闭包是的函数的作用域对其他程序来说时不可见的。
var myobject = (function () {
var value = 0;
return{
incremnet: function (inc){
this.value += typeof inc === 'number'? inc : 1;
}
};
}());
我们并没有把一个函数赋值给myobject。我们把调用该函数后返回的结果赋值给它。该函数返回一包含一个方法的对象,并且这些方法继续享有访问value变量的特权。
个人理解:返回的是一个对象,这个对象包含incremnet 方法,注意,这个被新定义的对象,是可以对value进行操作的。(因为incremnet对value进行了自增)value这个属性也会一直在内存中存在(不会被销毁)。所以每次调用myobject时, value都会自增。不会被清零。而myobject被调用后就会被销毁。“闭包”的重点在这个“闭”字。你看不到value的存在,但是它在内存中犹如一个“全局”变量。闭包的价值就在于它不会污染真正的全局变量,时仅对这个函数而言的"全局"变量。
喜欢的童鞋点个赞 ^ ^,帮助我做的更好。
也欢迎大家指正。
参考链接:「每日一题」JS 中的闭包是什么?
JavaScript中闭包的概念、原理、作用及应用