《JavaScript權威指南》讀書筆記——JavaScript核心

前言

這本由David Flanagan著做,並由淘寶前端團隊譯的《JavaScript權威指南》,也就是咱們俗稱的「犀牛書」,算是JS界公認的「聖經」了。本書較厚(有1004頁),讀起來頗費功夫,但做爲JavaScript(下文簡稱:JS)相關從業者,我仍是鼎力推薦,必定要讀完這本經久不息,好評如潮的JS「聖經」(若是您有耐心的讀完,以爲還不錯的,博客最後附有購買本書的優惠券,可自行領取)。javascript

說完本書重要性,下面重點介紹一下本書做者寫書的邏輯性,簡單來講本書分爲四部分,第一部分:JS核心;第二部分:客戶端JS;第三部分:JS核心參考和第一部分相呼應,是JS核心的重點概括和講解,也是第一部分的總結和昇華部分,因此建議看完第一部分以後能夠直接去看第三部分;第四部分:客戶端JS參考,和第三方的模式同樣,也是第二部分的總結、提煉、講解已經昇華。html

因此總體來講其實本書能夠分爲2部分,第一部分:js的核心;第二部分:客戶端js;前端

js的核心講的是js的最基礎的邏輯、原理、方法、屬性、以及使用;而客戶端js和服務器端js,只是做爲js語言的一種實踐部分,是js語言的一種使用場景,而後在具體場景中一些細化的使用。而本文只是整理了第一部分:JS核心,結合我本身的理解,作一個總結和記錄。java

 

正文

1、JS的類型面試

按照數據類型劃分:正則表達式

  原始類型:Number、String、Boolean、Null、Undefined、Symbol(ES6加入,它的實例惟一,且不可改變,不能使用關鍵「new」聲明);編程

  對象類型:Object數組

擴展:普通的js對象是「命名值」的無序集合,js一樣定義了一種特殊對象——數組(array),表示帶編號的有序集合。服務器

ES6新出了鍵控集合:Set和Map,Set集合值惟一,不會重複;Map存儲的爲鍵值對。閉包

JS還定義了另外一種特殊對象——函數。若是函數用new來初始化一個新建對象,咱們稱爲構造函數(constructor),每一個構造函數定義一類對象,除了數組(array)類和函數(Function)類以外,還有日期(Date)類、正則(RegExp)類、錯誤(Error)類都是js的核心類。

 

2、JS中的算術運算

算術運算符除了+、-、*、/、%(求餘運算符,求整數後的餘數)、還有更復雜的運算經過定義Math對象的函數和常量來實現

複製代碼
Math.abs(-10);        // => 10:絕對值
Math.ceil(0.6);       // => 1.0:向上取整數
Math.floor(0.6);       // => 向下取整數
Math.round(0.6);       // =>:1.0:四捨五入
Math.random();         // => 0-1隨機數
Math.max(1, 3, 5);     // => 返回最高值
Math.min(1, -3, 50);   // => 返回最低值
Math.pow(2, 3);        // => 8:2的3次方
Math.PI;             // => π:圓周率
Math.sin(3);           // => 3的正弦值
Math.sqrt(30);        // => 平方根
Math.tan(100);        // => 正切
Math.acos(10);        // => 反餘弦值
Math.cos(100);        // => 餘弦值
Math.exp(100);        // => e的100次冪
複製代碼

點擊訪問更多

 

3、string的slice用法

string的slice()用法,提取字符串的一部分,返回一個新字符,不改變原來字符串(和array.slice用法一致)。

var str1 = "hello world";
str1.slice(1, 4);   // "ell":截取下標1到下標4,不包含最後一位
str1.slice(1);      //"ello world":截取下標1之後的全部字符
str1.slice(-3);    //"rld":截取後三位

點擊訪問更多String類的方法

 

4、JS中的「假值」

undefined、null、0、-0、""、NaN 這6個能夠轉換成false的值,稱做「假值」。

複製代碼
var exp1 = undefined;
if (exp1) {
    console.log("真");
} else {
    console.log("假");
}
//output:假
複製代碼

 

5、數字轉換的方法(科學技術或四捨五入)

Number轉換成字符串的場景提供了三種方法:

  • toFixed() => 根據小數點後指定位數將數字轉化成字符串,會進行四捨五入;
  • toExponential() => 使用指數計數法將數字轉換爲字符串;
  • toPrecision() => 根據指定的有效字位數將數字轉換成字符串;
複製代碼
var n = 123456.78;
n.toFixed(0);       //output:123457
n.toFixed(1);       //ouput:123456.8
n.toFixed(5);       //output:123456.78000
n.toExponential(1);    //output:1.2e+5
n.toPrecision(4);      //output:1.2346e+5
n.toPrecision(7);      //output:123456.8
n.toPrecision(10);     //output:123456.7800
複製代碼

 

6、parseInt()的「高級」玩法

parseInt()能夠接收第二個可選參數,這個參數指定了數字轉換的基數,有效的取值範圍是2-36.

parseInt("11", 5);    //6 => 1*5+1
parseInt("ff", 16);   //255 => 15*16+15
parseInt("077", 10);  //77 => 70*10+7

 

7、全局變量和"全局屬性"的delete

js聲明變量使用var和不用var的區別,大部分咱們使用的時候都是同樣的,例如:

var str1 = "hello";
str2 = "world!";
console.log("%s %s", str1, str2);
//output:hello world!

而在使用delete屬性時,使用var的變量是不容許刪除的,例如:

複製代碼
var str1 = "hello";
str2 = "world!";
this.str3 = "!!!";
delete str1;    //false
delete str2;    //true
delete str3;    //true
複製代碼

總結:使用var的變量,能夠理解爲全局變量,全局變量屬性是不可編輯的,而不使用var的能夠看作是聲明瞭一個全局屬性,等同於this.xxx=yyy,屬性是能夠編輯的,因此是能夠delete的。

 

8、JS的局部變量提高和塊級做用域

先來看代碼執行的結果(也是一道經典的js面試題):

複製代碼
var scope = "global";
function f() {
    console.log(scope);
    var scope = "local";
    console.log(scope);
}
f();
console.log(scope);
//output: undefined、local、global
複製代碼

這是什麼緣由形成的?爲何不是global/local/global呢?由於es5沒有塊級做用域,局部變量被提高到最前了聲明瞭,js解析器的機制形成的,上面的代碼相似於下面這段代碼:

複製代碼
var scope = "global";
function f() {
    var scope; //只聲明變量,變量前置
    console.log(scope);
    scope = "local";
    console.log(scope);
}
f();
console.log(scope);
//output: undefined、local、global
複製代碼

因此一般來講,在做用域裏面變量聲明的代碼要放在代碼的最頂部,這是一個很是不錯的編程習慣,也能夠避免一些沒必要要的問題。

 

9、特殊的Date類型轉換

若是我告訴你typeof(new Date()+1)和typeof(new Date-1)的值不一樣你信嗎?

下面來看具體代碼:

var now = new Date();
typeof (now + 1);     //output:string
typeof (now - 1);     //output:number
now == now.toString(); //output:true

那上面的問題是怎麼形成的,typeof(now+1)不該該是number類型嗎?

緣由分析:

  「+」 有兩種含義,一個是字符串鏈接,一個是加法。

  類型轉換的時候,默認先調用valueOf,而後才調用toString,而Date類型除外,因此對於new Date()的時候優先,調用的是toString(),而「+」操做是把他當成了字符串鏈接而不是數字相加。

  「-」的時候,只有減法的含義,也就是說優先調用valuleOf,因此結果爲number類

 

10、js的繼承機制

繼承機制:js是經過原型鏈實現繼承的。簡單實現以下:

複製代碼
function Animal(name) {
    this.name = name || 'Animal';
    this.sleep = function () {
        console.log(this.name + '正在睡覺!');
    }
}
Animal.prototype.eat = function (food) {
    console.log(this.name + '正在吃:' + food);
};
function Cat() {
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
複製代碼

更多的能夠查看阮一峯老師的:Javascript繼承機制的設計思想型

 

11、Array的高級用法

1.slice和splice區別

雖然都是截取數組然而slice和splice的區別很大,接下來具體來看。

先說slice

slice定義:方法返回一個從開始到結束(不包括結束)選擇的數組的一部分淺拷貝到一個新數組對象。原始數組不會被修改。

var array = ["apple", "banana", "cherry", "dates", "fig"];
array.slice(1, 4);    //["banana", "cherry", "dates"]
array.slice(1);       //["banana", "cherry", "dates", "fig"]
array.slice(-2);      //["dates", "fig"]
console.log(array);     //["apple", "banana", "cherry", "dates", "fig"]
Array.prototype.slice(x,y); 第一位參數爲截取開始下標,截取的時候包含此下標,第二位參數缺省參數,若是不填寫,標識截取到數組的最後一位,若是填寫了,標識截取到下標的位置,截取元素不包含最後一位,截取不改變原來數組。
 
splice部分
splice定義:方法經過刪除現有元素和/或添加新元素來更改一個數組的內容。
代碼1:
//方法經過刪除現有元素和/或添加新元素來更改一個數組的內容。
var array = ["apple", "banana", "cherry", "dates", "fig"];
array.splice(2, 2); //從下標2開始截取,截取2個
console.log(array); //["apple", "banana", "fig"]

代碼2:

var array = ["apple", "banana", "cherry", "dates", "fig"];
array.splice(2); //從下標2開始截取,截取到最後
console.log(array); //["apple", "banana"] 

代碼3:

var array = ["apple", "banana", "cherry", "dates", "fig"];
array.splice(2, 2, "plum", "orange"); //截取下標2到後面2個元素替換成"plum", "orange"
console.log(array); //["apple", "banana", "plum", "orange", "fig"]

小技巧:可使用var newArray = array.splice();實現數組複製。

 

2.length的另外一種用法

var array = ["apple", "banana", "cherry", "dates", "fig"];
array.length = 3; //["apple", "banana", "cherry"]
array.length = 0; //[] => 刪除全部元素

 

3.reduce()

定義:方法對累加器和數組中的每一個元素(從左到右)應用一個函數,將其減小爲單個值。

var array = [10, 5, 20, 15];
var sum = array.reduce(function (x, y) { return x + y }, 0);       //求和
var product = array.reduce(function (x, y) { return x * y }, 0);    //求積
var max = array.reduce(function (x, y) { return (x > y) ? x : y }); //求最大值

 

4.every()和some()

定義:數組的邏輯判斷,對每個元素進行判斷,返回true或者false.

every()每個元素都要知足條件纔會返回true,some()其中一項知足條件即會爲true.

複製代碼
function fun(element, index, array) {
    return element > 10;
}
[2, 5, 8, 1, 4].some(fun);      // false
[12, 5, 8, 1, 4].some(fun);     // true

[12, 5, 8, 1, 4].every(fun);    // false
[12, 15, 18, 11, 14].every(fun);  // true
複製代碼

 

5.map()

定義:將調用數組的每個元素傳遞給指定的函數,並返回一個新的數組,不會改變老數組。

var array = [1, 4, 9, 16];
var map = array.map(x => x * 2);    //[2, 8, 18, 32]

 

6.Arguments.callee

定義:當前正在執行的函數.

在匿名函數中使用Arguments.callee引用自身,以便實現遞歸。代碼以下:

複製代碼
var fun = function (x) {
    console.log(x);
    if (x < 1) {
        return 1;
    }
    return x + arguments.callee(x - 1);
}
fun(3);   //7 => 3+2+1+1
複製代碼

 

7.sort()排序規則的理解 

sort()是能夠介紹一個匿名函數做爲排序規則的,例如:

var array = [3, 9, 3, 12, 5, 8, 1, 4];
array.sort(function (a, b) { return a - b; }); //[1, 3, 3, 4, 5, 8, 9, 12]

理解:a-b獲得一個值,而這個正常的值將按照數字的正常規則進行排序,也就是 負數=>0=>正數,因此理解a-b不能單純的理解他爲一個boolean值,而是根據a-b給數組一個排序規則,若是須要倒敘的話就用b-a.

點擊訪問更多Array基礎操做方法 

 

12、高階函數

定義: 高階函數就是操做函數的函數,它接受一個或多個做爲參數,並返回一個新函數。

function sum(x, y, f) {
    return f(x) + f(y);
}
console.log(sum(-5, 6, Math.abs));

 

十3、正則表達式字符

[...]    方塊內任意字符
[^...]   非方塊內任意字符
\w    [a-zA-Z0-9]
\W    [^a-zA-Z0-9]
\d    [0-9]
\D    [^0-9]

點擊訪問更多

 

十4、解構賦值

let [x, y] = [1, 2];
[x, y] = [x + 1, y + 1];
[x, y] = [y, x];
console.log(x, y);  // 3 2

 

十5、閉包

「閉包」這個詞剛開始開的時候就頭皮發麻,感受很「高大上」難以理解,其實掌握以後,發現也挺好用的,下面介紹一下我對於閉包的理解。

定義:閉包就是能夠訪問一個函數局部(私有)變量的方法。

複製代碼
var Cat = function () {
    var name = "cat";
    var age = 2;
    this.getName = function () {
        return name;
    }
    this.getAge = function () {
        return age;
    }
}
var cat = new Cat();
console.log(cat.name);        //undefined
console.log(cat.age);         //undefined
console.log(cat.getName());    //cat
console.log(cat.getAge());     //2
複製代碼

如上代碼:利用閉包能夠給用特權的方法訪問私有屬性,保證了私有變量不被修改和污染,固然根據實際需求能夠設置經過方法修改私有屬性也是可行的。

 


出處:https://www.cnblogs.com/vipstone/p/8371824.html

相關文章
相關標籤/搜索