1.6種值會為假(==false),分別是false,null,undefined,' ',0,NaN
2.typeof有6種值,分別是'number','string','boolean','undefined','function','object';其中typeof(null),結果是'object'
3.number類型總是64位浮點數,兩個整數相除也可能出現非整數結果
4.如果第一個運算數的值為假,那么運算符&&產生它的第一個運算數的值.否則,它產生第二個運算數的值.如,可利用&&運算符避免檢索undefined引起的異常
flight.equipment //undefinedflight.equipment.model //throw"TypeError"flight.equipment && flight.equipment.model //undefined
5.如果第一個運算數的值為真,那么運算符||產生它的第一個運算數的值.否則,它產生第二個運算數的值.如,可利用||運算符來填充默認值
var status = flight.status || "unkonwn"
6.對象通過引用來傳遞,永遠不會被拷貝
7.當我們對某個對象的屬性做出改變時,不會觸及到該對象的原型.原型鏈只有在檢索值得時候,才會自下至上,直到object.prototype中去尋找,找到就用,然后停止尋找,都沒有就返回undefined,這個過程稱為委托.hasOwnProperty方法可以檢測對象擁有的獨特屬性.
8.通過for in語句迭代出的對象屬性包含其原型鏈上的屬性,且無序;而通過for語句根據對象的length循環出的屬性,只包含獨有屬性,且順序
9.delete可以刪除對象的屬性,不會觸及對象原型上的屬性
10.函數也是對象,對象字面量產生的對象擁有到Object.prototype的隱藏鏈接,函數對象擁有到Function.prototype(該原型對象本身鏈接到Object.prototype)的隱藏鏈接.每個函數對象在創建時也隨帶一個prototype屬性,它的值是一個擁有constructor屬性且值即為該函數的對象
11.每個函數在創建時附有兩個附加的隱藏屬性:函數的上下文(可調用)和實現函數行為的代碼;調用一個函數將暫停當前執行,傳遞控制權和參數給新函數.除了聲明時定義的形參,每個函數接收兩個附加的參數:this和arguments,arguments.callee代表函數自身,通常用於遞歸
12.參數this的值取決於調用的模式,javascript中一共有四種調用模式:
方法調用模式:當一個函數被保存為對象的一個屬性時,我們稱它為一個方法,一個方法被調用時,this綁定到該對象(只要函數被調用的時候用一個.點或者[subscript]下標方式調用,那么它被當做一個方法來調用)
函數調用模式:當一個函數並非一個對象的屬性時,那么它被當做一個函數來調用,this被綁定到全局對象;解決內部函數的this被指向全局的設計缺陷時,可以在外部var that=this;如在瀏覽器中,this = window;在node中,this = globe
構造器調用模式:如果在一個函數前面帶上new來調用,那么將創建一個隱藏鏈接到該函數的prototype成員的新對象,同時this將會被綁定到那個新對象上.
apply調用模式:this綁定到第一個參數,即傳入對象
13.函數的實參(arguments)和型參(parameters)的個數不匹配時不會報錯;如果實參多了,超出的將被忽略.如果實參過少,缺少的會被傳入undefined.
14.arguments並不是一個真正的數組,它只是一個類似數組的對象,除了length屬性,它缺少其它數組方法.
14.5 一個函數總會返回一個值,沒有指定返回值,則返回undefined.如果函數以new方式調用,且返回值不是一個對象,則返回this(該新對象)
15.javascript缺少
塊級作用域,所以,最好的做法是在函數體的頂部聲明函數中可能用到的變量
16.利用閉包來返回外部函數變量的方式,可以避免一個函數被加上new來使用
閉包:var quo = function (status){
return {
get_status : function () {
return status ;
}
};
};
var myQuo = quo ("amazed");
構造函數:
var Quo = function (status){
this.status =status;
};
var myQuo = new Quo("amazed");
17. 一個閉包的坑
var add_the_handles = function (nodes ) {
var i;
for(i = 0;i < nodes.length ; i+= 1) {
nodes[i].onclick = function (e){
alert(i);
}
}
};
add_the_handles 函數目的是給每個時間處理器一個唯一值(i).它未能達到目的是因為事件處理器函數綁定了變量i,而不是函數在構造時的變量i的值.
改正為以下寫法可達到目的:
var add_the_handles = function (nodes ) {
var i;
for(i = 0;i < nodes.length ; i+= 1) {
nodes[i].onclick = function (tempI){
return function(e){
alert(tempI);
};
}(i);
}
};
18.回調
模擬異步請求,避免客戶端被阻塞
request = prepare_the_request();
send_request_asynchronously(request,function(response){
display(response);
};
19.模塊(module)通過函數和閉包來創建,只暴露可用的public方法,其它似有方法全部隱藏,如果你不需要傳參數或者沒有一些特殊苛刻的要求的話,我們可以在最后一個}后面加上一個括號,來達到自執行的目的,這樣該實例在內存中只會存在一份copy.可通過模塊模式來實現單例模式
var theModule = (function(){
var i = 10;
return {
result :function(x) {
return x*i;
}
};
}());
調用:theModule.result(5);
20.通用遞歸記憶函數,加入一個記憶參數,可以減少遞歸函數的調用次數,顯著提高效率
var memoizer = function (memo,fundamental) {
var shell = function (n) {
var result = memo[n];
if(typeof result !== 'number') {
result = fundamental(shell,n);
memo[n] = result;
}
return result;
};
return shell;
};
var shell = function (n) {
var result = memo[n];
if(typeof result !== 'number') {
result = fundamental(shell,n);
memo[n] = result;
}
return result;
};
return shell;
};
調用:
var fibonacci = memoizer([0,1],function(shell,n){
return shell(n-1)+shell(n-2);
return shell(n-1)+shell(n-2);
});
console.log(fibonacci(10));
21.當一個函數對象被創建時,Function構造器產生的函數對象會運行類似代碼: this.prototype = {constructor : this};所有的構造器函數都約定命名成為字母大寫的形式,但更好的備選方案是不適用new
22.構造器函數要接受一大串參數的寫法:
不建議寫法: var myObject = maker(f,l,m,c,s);
建議寫法: var myObject = maker({
first : f,
last: l,
state:s,
city:c
});
好處是多個參數可以任意排序,如果有默認值,可以忽略到一些參數,且代碼更易讀
23.在一個純粹的原型模式中,我們會摒棄類,轉而專注於對象,一個新對象可以繼承一個就對象的屬性
24.在偽類模式與模塊模式中,盡量選擇后者,
函數化構造器偽代碼模板
var constructor = function (spec ,my) {
var that,其他的私有實例變量;
my = my || {};
把共享的變量和函數添加到my中
that = 一個新對象
添加給that的特權方法
return that;
}
25.javascript的數組是一種擁有一些類數組特性的對象.它把數組的下標轉變成字符串,用其作為屬性,比普通屬性多了一個可以用整數作為屬性名的特性.且繼承自Array.prototype,多了一個length屬性;javascript同一個數組的元素可以是混合類型,且沒有上界.
26. var numbers = ['zero','one','two'];
numbers[numbers.length] = 'three'; 等價於
numbers.push('three');
27.是否數組檢測
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
28.javascript中的糟粕
全局變量 :越少越好
作用域 :無塊級作用域,在每個函數開頭部分聲明所有變量
自動插入分號 :因此大括號風格需使用埃及括號
Unicode :javascript字符是16位的,只能覆蓋65535個字符
parseInt :增加第二個參數,明確進制,parseInt("08",10)
浮點數 :二進制浮點數不能正確的處理十進制小數,0.1+0.2不等於0.3,不過整數部分是精確的
NaN : typeof NaN === 'number' //true; NaN === NaN //false;
對象 :因為原型鏈的存在,javascript對象永遠不會有真的空對象
29.javascript中的雞肋
運算符 ==和!= :會試圖強制轉化判斷值的類型,規則復雜
with語句 :可能出現歧義,並影響處理器速度
eval :降低安全性,增加閱讀復雜性
continue :重構移出continue后,性能得到改善
++ -- :使代碼變得更隱晦
位運算符 :javascript沒有整數類型,位操作符將它們的運算數先轉換成整數,接着執行運算,然后再轉化回去,非常慢
function :不在if語句中使用function,盡量用var func = function... 的形式聲明
new :更好的應對策略是根本不去使用new
void :將返回undefined,沒有什么用,而且讓人困惑
總結: 這本書只有100多頁,定價高達49,開始第一感覺是比較貴;看完后領略到了物有所值,濃縮的都是精華,幾乎全部是干貨,連附錄都是干貨.在看過一門javascript的入門書后,再看此書,非常有利於知識的沉淀.