《JavaScript語言精粹》讀書筆記
阿新 • • 發佈:2019-01-13
表達 star turn ray 檢索 obj 就是 第四章 遞歸
第三章 對象
- 檢索
var obj = {a: 1, b:2, c:3}
obj[a] // obj.a
// 檢索結果是undefined 時用 || 或 && 避免錯誤
obj[a] && obj[b]
- 反射
var obj = { number: 111, airline: ‘dsdsds‘ } // hasOwnProperty檢測對象的屬性 console.log(typeof obj.number) // number console.log(obj.hasOwnProperty(‘number‘)) // true console.log(obj.hasOwnProperty(‘number1‘)) // false
- 枚舉
第四章 函數
調用
js中一共有4中調用模式:
- 方法調用模式
- 函數調用模式
- 構造器調用模式
apply調用模式
- 方法調用模式
//1 方法調用模式 var myObject = { value: 0, increment: function(inc) { this.value += typeof inc === ‘number‘ ? inc: 1; } } myObject.increment(); document.writeln(myObject.value)/// 1 myObject.increment(2); document.writeln(myObject.value) // 3 // 方法可以使用this訪問自己所屬的對象,所以他能從對象中取值或者對對象進行修改。 // this到對象的綁定發生在調用的時候。
- 函數調用模式
//2 函數調用模式 var add = function(a, b) { return a+ b; } var sum = add(3, 4); // 7 // 給myObject 增加一個double方法 myObject.double = function() { var that = this; var helper = function () { that.value = add(that.value, that.value); } helper(); // 以函數的形式調用helper } // 以方法的形式調用double myObject.double(); console.log(myObject.value) // 6 // 方法調用函數時,this被綁定到全局對象, 解決方案 : 定義一個變量,將this賦值給它,name內部函數就可以通過that訪問到this
- 構造器調用模式 不推薦
//3 構造器調用模式 不推薦
var Quo = function(string) {
this.status = string;
}
// 給quo的所有實例提供一個名為get_status的公用方法
Quo.prototype.get_status = function() {
return this.status;
}
// 構造一個quo的實例
var myQuo = new Quo(‘confused‘);
document.writeln(myQuo.get_status()) // confused
// 如果在一個函數前面帶上new 來調用,那麽背地裏將會創建一個連接到該函數的prototype成員的新對象,同時this會被綁定到那麽新對象上。
// 使用閉包的方法來調用
var quo = function(status) {
return {
get_status: function() {
return status
}
}
}
var myQuo = quo(‘amazed‘)
console.log(myQuo.get_status()) //amazed
- Apply調用模式
// 4 Apply調用模式
// Apply方法讓我們構建一個參數數組傳遞給調用的函數,它允許我們選擇this的值。apply方法接收兩個參數,第1個是要綁定給this的值,第2個就是一個參數數組
var array =[3, 4];
var sum = add.apply(null, array);
alert(sum) // 7
// 構造一個包含status成員的對象
var statusObject = {
status: ‘A-OK‘
}
// statusobject並沒有繼承自Quo.protoptype,但我們可以在statusobject上調用
// get_status方法,盡管statusObject並沒有一個名為get_status的方法
var status = Quo.prototype.get_status.apply(statusObject);
console.log(status) // A-OK
擴充類型功能
// js允許給語言的基本類型擴充功能; 可以給object。prototype添加方法,可以讓該方法對所有對象都可用。
// 這樣的方式對函數,數組,字符串,數字,正則表達式和布爾值同樣適用
Function.prototype.method= function(name, func) {
this.prototype[name] = func
return this
}
// 通過給function.prototype 增加一個method方法,我們下次給對象曾加方法的時候就不必鍵入prototype這幾個資產,省略掉了一點麻煩
// 1 給Number.prototype 增加一個integer方法來改善它,他會根據數字的正負來判斷是使用Math.ceiling 還是Math.floor
Number.method(‘integer‘, function() {
return Math[this<0 ? ‘ceil‘: ‘floor‘](this)
})
document.writeln((-10/3).integer()) // -3
作用域
var foo = function() {
var a =3, b=5;
var bar = function() {
var b=7, c=11;
// a =3 b =7 c=11
a+=b+c // a=21 b=7 c= 11
}
// a=3 b=5 c undefined
bar()
// a=21 b 5
}
閉包
// 創建一個名為quo的構造函數
// 它構造帶有get_status方法和status私有屬性的一個對象
var quo = function (status) {
return {
get_status: function () {
return status
}
}
}
// 構造一個quo實例
var myQuo = quo(‘amazed‘)
console.log(myQuo.get_status()) //amazed
// 這個quo函數設計成無需再前面加上new來使用,所以名字也沒有首字母大寫。當我們調用quo時,它返回包含
// get_status方法並不是訪問該參數的一個副本,它訪問的就是該參數本身。這是可能的;
// 因為該函數可以訪問它被創建時所處的上下文環境。 這就稱為閉包。
// 定義一個函數,它設置一個DOM節點為黃色,然後把它漸變為白色
var fade = function (node) {
var level = 1;
var step = function () {
var hex = level.toString(16);
node.style.backgroundColor = ‘#FFFF‘ + hex + hex;
if (level < 15) {
level += 1;
setTimeout(step, 100);
}
}
setTimeout(step, 100);
}
fade(document.body)
記憶
// 函數可以將先前操作的結果記憶在某個對象裏,從而避免無謂的重復運算。這種優化被稱為記憶
// 實現一個遞歸函數來計算Fibonacci數列
// 一個斐波那契數列 數字是之前兩個斐波那契數字之和。 最前面的兩個數字是0 和1
var fibonacci = function(n) {
return n<2 ? n : fibonacci(n-1) +fibonacci(n-2)
}
for(var i=0;i<=10; i+=1){
document.writeln(‘//‘+i+‘:‘ +fibonacci(i))
//0:0 //1:1 //2:1 //3:2 //4:3 //5:5 //6:8 //7:13 //8:21 //9:34 //10:55
}
// 優化
// 我們在一個名為memo的數組裏保存我們的存儲結果,存儲結果可以隱藏在閉包中。當函數被調用時,
// 這個函數首先檢查結果是否已存在,如果已經存在,就立即返回這個結果。
var fibonacci =function(n) {
var memo = [0,1]
var fib=function(n) {
var result =memo[n]
if(typeof result !== ‘number‘) {
result = fib(n-1) +fib(n-2)
memo[n]=result
}
return result
}
return fib
}()
for(var i=0;i<=10; i+=1){
document.writeln(‘//‘+i+‘:‘ +fibonacci(i))
//0:0 //1:1 //2:1 //3:2 //4:3 //5:5 //6:8 //7:13 //8:21 //9:34 //10:55
}
// 推廣
// 我們memoizer函數取得一個初始化memo數組和formula函數。它返回一個管理meno存儲和在需要時調用formula函數的recur函數。
// 我們把這個recur函數和它的參數傳遞給formula函數
var memoizer =function (memo, formula){
var recur = function(n){
var result = memo[n]
if(typeof result !== ‘number‘) {
result = formula(recur, n)
memo[n] =result
}
return result
}
return recur
}
// 現在,我們可以使用memoizer函數來定義fibonacci函數, 提供其初始的memo數組和formula函數
var fibonacci = memoizer([0,1], function(recur, n) {
return recur(n-1) +recur(n-2)
})
var factorial = memoizer([1,1], function(recur, n) {
return n * recur(n-1)
})
js易混淆的地方
// 區分數組和對象
var is_array = function(value) {
return Object.prototype.toString.apply(value) === ‘[object Array]‘
}
console.log(is_array([])) // true
第八章 方法
Array
- array.concat()
// concat方法產生一個新數組,它包含一份array的淺復制並把一個或多個參數item附加在後面,如果參數item是一個數組
// name它的每個元素會被分別添加 類似於 array.push()
var a = [1,2,3]
var b= [4,5,6]
console.log(a.concat(b, true)) //[1, 2, 3, 4, 5, 6, true]
- array.join()
- array.pop()
// pop移除數組中最後一個元素並返回改元素,如果array是空,它返回undefined
var a = [1,2,3]
var c= a.pop()
console.log(c) // 3
console.log(a)
- array.push()
- array.reverse()
- array.shift()
array.slice()
- array.sort() 排序
var n = [4,6,7,1,5]
n.sort(function(a,b) {
return a-b
})
console.log(n) // [1, 4, 5, 6, 7]
var m = [‘aa‘,‘bb‘, ‘a‘, 4,8,16,23,42]
m.sort(function(a, b) {
if(a ===b) {
return 0
}
if(typeof a === typeof b) {
return a< b? -1 : 1
}
return typeof a <typeof b ? -1 :1
})
console.log(m) //[4, 8, 16, 23, 42, "a", "aa", "bb"]
- array.splice()
array.unshift()
Function
- function.apply(thisArg, argArray)
apply方法調用function,傳遞一個會綁定到this上的對象和一個可選的數組作為參數。
apply方法被用在apply調用模式中
Function.method(‘bind‘, function(that) {
// 返回一個函數,調用這個函數就像調用那個對象 的一個方法
var method = this,
slice = Array.prototype.slice,
args = slice.apply(arguments, [1])
return function() {
return method.apply(that, args.concat(slice.apply(arguments, [0])))
}
})
var x = function() {
return this.value
}.bind({value: 666})
alert(x())
object.hasOwnProperty(name)
如果這個object包含一個名為name的屬性,n那麽hasOwnProperty方法返回trueRegExg
regexp.exec(string)
如果匹配成功regexp和字符串string,它會返回一個數組。
數組中的下標未0的元素將包含正則表達式regexp匹配的子字符串regexp.test(string)
返回 true 和false
String
- string.charAt()
- string.charCodeAt()
- string.concat()
- string.indexOf()
返回 -1 未找到 找到返回位置 - string.lastIndexOf()
- string.match(regexp)
字符串和正則匹配 和全局匹配 g - string.replace(searchValue, replaceValue)
對string進行查找和替換操作,並返回一個新的字符串。
var reg = /\((\d{3})\)/g
var p = ‘(555)666-1212‘.replace(reg, ‘$1-‘)
console.log(p) //555-666-1212
- string.search(regexp)
search方法和indexOf方法類似,接收一個正則表達式對象作為參數而不是一個字符串
找到匹配 返回第一匹配的位置,沒有返回-1
var text = ‘and in it he says "Any damn fool could‘
var pos = text.search(/["‘]/) // 18
- string.slice(start, end)
如果start/end是負數,他將與string.length相加。end參數是可選參數,默認string.length - string.split(separator, limit)
把string分割成片段來創建一個字符串數組。 - string.substring(start, end)
和slice()的用法一樣, 不能處理負數參數 - string.toLocaleLowerCase()
- string.toLocaleUpperCase()
《JavaScript語言精粹》讀書筆記