高程(第五章) 引用類型

1 Object類型

建立對象實例:javascript

  • new操做符後跟Object構造函數前端

ver person = new Object();
person.name = "Nicolas";
person.age = 29;
  • 對象字面量表示法java

var person = {
    name : "Nicholas",
    age : 29
}

經過對象字面量定義對象時,實際上不會調用Object構造函數segmentfault

2 Array類型

建立數組:數組

  • 使用Array構造函數瀏覽器

var colors = new Array(20);    //new能夠省略,20表示數組長度
  • 數組字面量表示法安全

var colors = ["red", "blue", "green"];

2.1 檢測數組

  • 使用instanceof操做符app

console.log(value instanceof Array);    //只有一個全局做用域時使用

若是網頁中包含多個框架,那實際上就存在兩個以上不一樣的全局執行環境,從而存在兩個以上不一樣版本的Array構造函數框架

  • 使用Array.isArray()方法dom

console.log(Array.isArray(value));    //肯定value是否數值,無論它是在哪一個全局執行環境中建立的

2.2 轉換方法

  • toLocaleString()

  • toString()

  • valueOf()

  • join()

var colors = ["red", "green", "blue"];
console.log(colors.join("||"));        //red||green||blue

2.3 棧方法

  • push():在數組末尾添加項,返回數組長度

  • pop():移除數組最後一項,返回移除的項

2.3 隊列方法

  • shift():移除數組第一項,返回移除的項

  • unshift():在數組前端添加項,返回數組長度

2.5 重排序方法

  • reverse():反轉數組的順序

  • sort():按照升序排列數組項

sort()方法會調用每一個數組項的toString()轉型方法,而後比較獲得的字符串
可接收一個比較函數做爲參數,比較函數接收兩個參數,若是第一個參數應該位於第二個以前則返回一個負數,若是兩個參數相等則返回0,若是第一個參數應該位於第二個以後則返回一個正數;以下:

function compare(value1, value2){
    return value2 - value1;    //降序排序
}

2.6 操做方法

  • concat():用於拼接數組

  • slice():用於獲取數組中的某幾個項

  • splice():主要用途是向數組的中部插入項

2.7 位置方法

  • indexOf():從數組的開頭查找某一項

  • lastIndexOf():從數組的末尾查找某一項

兩個方法都返回要查找的項在數組中的索引,沒找到的狀況下返回-1

2.8 迭代方法

  • every():對數組中的每一項運行給定函數,若是該函數對每一項都返回true,則返回true。

  • filter():對數組中的每一項運行給定函數,返回該函數會返回true的項組成的數組。

  • forEach():對數組中的每一項運行給定函數,這個方法沒有返回值。

  • map():對數組中的每一項運行給定函數,返回每次函數條用的結果組成的數組

  • some():對數組中的每一項運行給定函數,若是該函數對任一項返回true,則返回true。

以上方法都不會修改數組中的包含的值

2.9 歸併方法

如下兩個方法都會迭代數組的全部項,而後構建一個最終返回的值。這兩個方法都接收兩個參數:一個在每一項上調用的函數和(可選的)做爲歸併基礎的初始值。傳入的函數接收4個參數:前一個值、當前值、項的索引和數組對象。這個函數的返回值會做爲參數自動傳給下一項。

  • reduce():從數組第一項開始,逐個遍歷到最後

  • reduceRight():從數組的最後一項開始,向前遍歷到第一項

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
    return prev + cur;
});
alert(sum);     //15

reduceRight()除了遍歷方向的不一樣以外,與reduce()方法徹底一致。

5 Function 類型

函數是對象,所以函數名實際上也是一個指向函數對象的指針,不會與某個函數綁定。

function sum(num1, num2){        //會先進行函數聲明提高
    return num1 + num2;
}

var sum = function(num1, num2){        //不會進行函數聲明提高
    return num1 + num2;
}

var sum = new Function("num1", "num2", "return num1 + num2");    //不推薦,會致使解析兩次代碼

5.3 做爲值的函數

由於ECMAScript中的函數名自己就是變量,因此函數也能夠做爲值來使用。也就是說,不只能夠像傳遞參數同樣把一個函數傳遞給另外一個函數,也能夠將一個函數做爲另外一個函數的結果返回。

function createComparisonFunction(propertyName){
    return function(object1, object2){
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];
    }
    if(value1 < value2){
        return -1;
    }else if(value1 > value2){
        return 1;
    }else{
        return 0;
    };
}

var data = [{name : "Zachary", age : 28}, {name : "Nicholas", age : 29}];

data.sort(createComparisonFunction("name"));
console.log(data[0].name);        //Nicholas

data.sort(createComparisonFunction("age"));
console.log(data[0].name);        //Zachary

5.4 函數內部屬性

在函數內部,有兩個特殊的對象:arguments和this

  • arguments有一個名叫callee的屬性,該屬性是一個指針,指向擁有這個arguments對象的函數

function factorial(num){
    if(num <= 1){
        return 1;
    }else{
        return num * arguments.callee(num - 1);    //解除耦合
    }
}
  • 函數內部的另外一個特殊對象是this,this引用的是函數執行的環境對象——或者也能夠說是this值(當在網頁全局做用域中調用函數時,this對象引用的就是window)

ECMAScript5也規範化了另外一個函數對象的屬性:caller。這個屬性中保存着調用當前函數的函數的引用,若是是在全局做用域中調用當前函數,它的值爲null。

function outer(){
    inner();
}

function inner(){
    console.log(arguments.callee.caller);    //爲了實現更鬆散的耦合
}

outer();

當函數在嚴格模式下運行是,訪問arguments.callee會致使錯誤。ECMAScript 5 還定義了arguments.caller屬性,但在嚴格模式下訪問它也會致使錯誤,而在非嚴格模式下這個屬性始終是undefined。定義arguments.callee屬性是爲了分清arguments.caller和函數的caller屬性。以上變化都是爲了增強這門語言的安全性,這樣第三方代碼就不能在相同的環境裏窺視其餘代碼了。
嚴格模式還有一個限制:不能爲函數的caller屬性賦值,不然會致使錯誤。

5.5 函數屬性和方法

每一個函數都包含兩個屬性:lengthprototype

  • length:表示函數但願接受的命名參數的個數

  • prototype:對於ECMAScript中的引用類型而言,prototype是保存它們全部實例方法的真正所在

諸如toStr()和valueOf()等方法實際上都保存在prototype名下,只不過是經過各自對象的實例訪問罷了。在ECMAScript 5 中,prototype屬性是不可枚舉的,所以使用for-in沒法發現

每一個函數都包含兩個非繼承而來的方法:apply()call()。這兩個方法的用途都是在特定的做用域中調用函數,實際上等於設置函數體內this對象的值

  • apply():接收兩個參數,第一個是在其中運行函數的做用域,第二個是參數數組

  • call():與apply()做用相同,變化在於傳遞給函數的參數必須逐個列舉出來

在不給函數傳遞參數的狀況下,使用哪一個方法都無所謂

window.color = "red";
var o = {color : "blue"};

function sayColor(){
    console.log(this.color);
}

sayColor();                //red

sayColor.call(this);    //red
sayColor.call(window);    //red
sayColor.call(o);        //blue

使用call()(或apply())來擴充做用域的最大好處,就是對象不須要與方法有任何耦合關係

ECMAScript還定義了一個方法:bind()。這個方法會建立一個函數的實例,其this值會被綁定到傳給bind()函數的值

window.color = "red";
var o = {color : "blue"};

function sayColor(){
    console.log(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor();        //blue

每一個函數繼承的toLocaleString()toString()valueOf()方法始終都返回函數的代碼

6 基本包裝類型

爲了便於操做基本類型值,ECMAScript還提供了3個特殊的引用類型:Boolean、Number和String。這些類型與其餘引用類型類似,但同時也具備與各自的基本類型相應的特殊行爲。實際上,每當讀取一個基本類型值得時候,後臺就會建立一個對應的基本包裝類型的對象,從而讓咱們可以調用一些方法來操做這些數據

var s1 = "some text";
var s2 = s1.substring(2);

進行以上操做,後臺會自動完成如下一系列處理:

  1. 建立String類型的一個實例;

  2. 在實例上調用指定的方法;

  3. 銷燬這個實例。

能夠將以上三個步驟想象成是執行了下列ECMAScript代碼:

var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;

除非必要時,不然不推薦顯式地調用Boolean、Number和String來建立基本包裝類型的對象,由於這種作法很容易讓人分不清本身是在處理基本類型仍是引用類型的值。對基本包裝類型的實例調用typeof會返回"object",並且全部基本包裝類型的對象在轉換爲布爾類型時值都是true

Object構造函數也會像工廠方法同樣,根據傳入值的類型返回相應基本包裝類型的實例:

var obj = new Object("some text");
console.log(obj instanceof String);        //true

使用new調用基本包裝類型的構造函數,與直接調用同名的轉型函數時不同的:

var value = "25";
var number = Number(value);        //轉型函數
console.log(typeof number);        //"number"

var obj = new Number(value);    //構造函數
console.log(typeof obj);        //"object"

6.1 Boolean類型

Boolean類型是與布爾值對應的引用類型

var booleanObject = new Boolean(true);

boolean類型的常見問題:

var falseObject = new Boolean(false);
var result = falseObject && true;
console.log(result);    //true

var falseValue = false;
result = falseValue && true;
console.log(result);    //false

console.log(typeof falseObject);        //object
console.log(typeof falseValue);            //boolean
console.log(falseObject instanceof Boolean);        //true
console.log(falseValue instanceof Boolean);        //false

6.2 Number 類型

Number類型是與數字值對應的引用類型

var numberobject = new Number(10);

可用toString()方法傳遞一個表示基數的參數,告訴它返回幾進制數值的字符串形式

除了繼承的方法(valueOf()、toLocaleString()、toString())外,Number類型還提供了一些用於將數值格式化爲字符串的方法:

  • toFixed():按照指定的小數位返回數值的字符串表示

  • toExponential():該方法返回以指數表示法(e表示法)表示的數值的字符串形式。toExponential()也接收一個參數,指定輸出結果中的小數位數

  • toPrecision():該方法可能會返回固頂大小(fixed)格式,也可能返回指數(exponential)格式;具體規則是看哪一種格式最合適。這個方法接收一個參數,即表示數值的全部數字的位數(不包括指數部分)

6.3 String 類型

String類型是字符串的對象包裝類型

var stringObject = new String("hello world");

String類型的每一個實例都有一個length屬性,表示字符串中包含多個字符

var stringValue = "傑神 ,shuai /' ";
console.log(stringValue.length);    //12

即便字符串中包含雙字節字符(不是佔一個字節的ASCII字符),每一個字符也仍然算一個字符

7 單體內置對象

ECMA-262對內置對象的定義是:「由ECMAScript實現提供的、不依賴於宿主環境的對象,這些對象在ECMAScript程序執行以前就已經存在。」意思就是說,開發人員沒必要顯式地實例化內置對象,由於它們已經實例化了。除了Object、Array和String等內置對象,ECMA-262還定義了兩個單體內置對象:Global和Math

JavaScript原生對象及擴展

7.1 Global對象

Global(全局)對象能夠說是ECMAScript中最特別的一個對象了,由於無論從什麼角度上看,這個對象都是不存在的。不屬於任何其餘對象的屬性和方法,最終都是它的屬性和方法。諸如isNaN()isFinite()parseInt()以及parseFloat(),實際上都是Global對象的方法

Global對象還包含其餘一些方法:

  • Global對象的encodeURI()encodeURIComponent()方法能夠對URI(Uniform Resource Identifiers,通用資源標識符)進行編碼,以便發送給瀏覽器

  • eval():該方法就像是一個完整的ECMAScript解析器,它只接受一個參數,即要執行的ECMAScript(或JavaScript)字符串

eval("alert('hi')");
//上行代碼的做用等價於下面這行代碼
alert("hi");

特殊的值undefined、NaN、以及Infinity都是Global對象的屬性。此外,全部原生引用類型的構造函數,像Object和Function,也都是Global對象的屬性。

ECMAScript 5 明確禁止給undefined、NaN和Infinity賦值,這樣作即便在非嚴格模式下也會致使錯誤

7.1.4 window對象

ECMAScript雖然沒有指出如何訪問Global對象,但Web瀏覽器都是將這個全局對象做爲window對象的一部分加以實現的。所以,在全局做用域中聲明的全部變量和函數,都成爲了window對象的屬性

JavaScript中的window對象除了扮演ECMAScript規定的Global對象的角色外,還承擔了不少別的任務

另外一種取得Global對象的方法是使用如下代碼:

var global = function(){
    return this;
}();

7.2 Math對象

ECMAScript還爲保存數學公式和信息提供了一個公共位置,即Math對象。與咱們在JavaScript直接編寫的計算功能相比,Math對象提供的計算功能執行起來要快得多。Math對象中還提供了輔助完成這些計算的屬性和方法

7.2.1 Math對象的屬性

  • Math.PI:π的值

  • ……

7.2.2 min()和max()方法

min()和Max()方法用於肯定一組數值中的最小值和最大值。這兩個方法均可以接收任意多個數值參數

7.2.3 舍入方法

  • Math.ceil()

  • Math.floor()

  • Math.round()

7.2.4 random()方法

random()方法返回大於等於0小於1的一個隨機數。
套用下面的公式,就能夠利用Math.random()從某個整數範圍內隨機選擇一個值

值 = Math.floor(Math.random()) * 可能值的總數 + 第一個可能的值

var num = Math.floor(Math.random() * 9 + 2);    //介於2到10之間的值
function selectFrom(lowerValue, upperValue){
    var choices = upperValue - lowerValue + 1;
    return Math.floor(Math.random() * choices + lowerValue);

    var num = selectFrom(2, 10);
    console.log(num);    //介於2到10之間的值
}


var colors = ["red", "green", "blue"];
var color = colors[selectFrom(0, colors.lenght-1)];
console.log(color);        //多是數組中包含的任何一個字符串
相關文章
相關標籤/搜索