国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Array.prototype.slice及其他Array方法

yibinnn / 2749人閱讀

摘要:方法真是一個有意思的東西,它可以改變函數(shù)調(diào)用時的值。所以前面的說法其實(shí)不對,所有的對象都可以被視為類數(shù)組,有的視為長度為的數(shù)組,沒有的,視為長度為的數(shù)組。

call方法真是一個有意思的東西,它可以改變函數(shù)調(diào)用時this的值。而我們知道,在函數(shù)里,this指向了調(diào)用這個函數(shù)的環(huán)境對象,比如一道經(jīng)典面試題:

var num = 2;
var obj = {
  num: 1,
  show: function () {
    console.log(this.num)
  }
};
var foo = obj.show;
obj.show();/* 顯示1;show是被obj調(diào)用的,所以this指向obj */
foo();/* 顯示2;相當(dāng)于global.foo(),所以this指向global,如果在瀏覽器里global就是window */

換句話說,如果一個對象obj上有方法foo,你可以通過obj.foo()調(diào)用;如果沒有obj上沒有方法foo,obj.foo()是會報錯的,但是,使用foo.call(obj),可以強(qiáng)行達(dá)到obj.foo()的效果,比如:

function foo(){
    console.log(this.num);
}
var obj = {
    num: 1
}
foo.call(obj);// 1

Array.prototype.slice.call的用處就是這樣,可以在array-like(類數(shù)組,就是長得像數(shù)組,但不是數(shù)組)的對象上強(qiáng)行使用slice方法,比如:Array.prototype.slice.call(arguments)就是把arguments對象轉(zhuǎn)化為數(shù)組。當(dāng)然,除了arguments,我們還能在HTMLCollectionNodeList身上使用。那么到底什么算是類數(shù)組呢?

有l(wèi)ength屬性的對象。

比如:

var obj1 = {
  0: "Tom",
  1: "Jack",
  2: "Jason",
  length: 3
}
var arr = [].slice.call(obj1);
console.log("arr: ", arr);/* [ "Tom", "Jack", "Jason" ] */

那如果沒有l(wèi)ength呢?

var obj1 = {
  0: "Tom",
  1: "Jack",
  2: "Jason"
}
var arr = [].slice.call(obj1);//* [] */

原來沒有l(wèi)ength屬性的對象也會被轉(zhuǎn)為數(shù)組,只不過認(rèn)為它length=0而已。

那如果對象的屬性沒有按照0-n順序乖乖排好呢?

var obj1 = {
  1: "Tom",
  3: "Jack",
  5: "Jason",
  7: "Dave",
  foo: "bar",
  length: 6
}
var arr = [].slice.call(obj1);/* [ , "Tom", , "Jack", , "Jason" ] */

原來轉(zhuǎn)化的時候,會以length為基礎(chǔ),生成一個長度為length的數(shù)組,obj的屬性是數(shù)組的有效index的話,就會把對應(yīng)值填入到對應(yīng)位置,其他的位置找不到值,就會填入undefined。

所以前面的說法其實(shí)不對,所有的對象都可以被視為類數(shù)組,有length的視為長度為length的數(shù)組,沒有的,視為長度為0的數(shù)組。

length屬性為基礎(chǔ)

這句話很重要。

另外,call方法的參數(shù)如果是原始值類型,會傳入它的自動包裝對象

var arr = [].slice.call("hello");

等價于:

var arr = [].slice.call(new String("hello"));/* [ "h", "e", "l", "l", "o" ] */

因?yàn)閚ew String("hello")就是
{
    0: "h",
    1: "e",
    2: "l",
    3: "l",
    4: "o",
    length: 5
}    

以上就是Array.prototype.slice.call的一些細(xì)節(jié),那么除了slice之外,Array對象還有很多其他的方法,這些方法是不是也能用到對象身上呢?

Array.prototype.join

join方法是把數(shù)組轉(zhuǎn)化為字符串的方法,具體表現(xiàn)不再贅述,看兩個例子:

var obj1 = {
  0: "Tom",
  1: "Jack",
  2: "Jason",
  length: 6
}
var arr = [].join.call(obj1, "-");// Tom-Jack-Jason---

var obj1 = {
  0: "Tom",
  1: "Jack",
  2: "Jason",
}
var arr = [].join.call(obj1, "-"); // ""

還是那句話,length為基礎(chǔ),沒有length屬性的,視為長度為0的數(shù)組。

Array.prototype.push

這個方法比較好玩:

var obj1 = {
  0: "Tom",
  1: "Jack",
  2: "Jason",
  length: 6
}
var arr = [].push.call(obj1, "Dave");
console.log("arr: ", arr);// 7,因?yàn)閜ush方法返回的是push之后array的操作數(shù)
console.log("obj: ", obj1);// { "0": "Tom", "1": "Jack", "2": "Jason", "6": "Dave", length: 7 }

可以看到obj1里新增屬性6,值為"Dave",并且length也更新為7,這說明調(diào)用push時會對原有對象進(jìn)行修改。
我們可以利用這個特性,比如當(dāng)我們需要一個obj1的類數(shù)組副本時:

var obj = {
  foo: "foo",
  bar: "bar",
  cei: "cei"
};
var copy = {};
for (var i in obj) {
  [].push.call(copy, obj[i])
}
console.log(copy);// { "0": "foo", "1": "bar", "2": "cei", length: 3 }

如果,沒有傳入length呢?

var obj1 = {
  0: "Tom",
  1: "Jack",
  2: "Jason"
}
var arr = [].push.call(obj1, "Dave");
console.log("arr: ", arr);// 1
console.log("obj: ", obj1);// { "0": "Dave", "1": "Jack", "2": "Jason", length: 1 }

這里的行為有些詭異,不過也更好地解釋了以length為基礎(chǔ)這句話:
沒有length的時候,認(rèn)為數(shù)組長度為0,并且會對obj進(jìn)行修改,把屬性0的值改為Dave.

那么,會舉一反三的話,對于pop, shiftunshift這三個方法的行為應(yīng)該能想象得出來,就不再贅述了。

Array.prototype.reverse
var obj1 = {
  0: "Tom",
  1: "Jack",
  2: "Jason",
  length: 6
}
var arr = [].reverse.call(obj1);
console.log("arr: ", arr);// { "3": "Jason", "4": "Jack", "5": "Tom", length: 6 }
console.log("obj: ", obj1);// { "3": "Jason", "4": "Jack", "5": "Tom", length: 6 }

reverse的話,arr === obj1

Array.prototype.sort
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].sort.call(obj1);
console.log("arr: ", arr);// { "0": "a", "1": "b", "2": "c", length: 6 }
console.log("obj: ", obj1);// { "0": "a", "1": "b", "2": "c", length: 6 }

sort也一樣,arr === obj1

Array.prototype.concat

concat的表現(xiàn)就不是我們意料之中的了:

var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}

var add = {
  foo: "foo",
  bar: "bar"
}
var arr = [].concat.call(obj1, add);
console.log("arr: ", arr);// [ { "0": "c", "1": "b", "2": "a", length: 6 }, "foo", "bar" ]
console.log("obj: ", obj1);// { "0": "c", "1": "b", "2": "a", length: 6 }
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].concat.call(obj1, "foo", "bar");
console.log("arr: ", arr);// [ { "0": "c", "1": "b", "2": "a", length: 6 }, "foo", "bar" ]
console.log("obj: ", obj1);// { "0": "c", "1": "b", "2": "a", length: 6 }

可以看到obj1并不會改變,不會像push一樣會接著形成一個類數(shù)組的對象.

Array.prototype.splice
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].splice.call(obj1, 0, 1);
console.log("arr: ", arr);// [ "c" ]
console.log("obj: ", obj1);// { "0": "b", "1": "a", length: 5 }
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].splice.call(obj1, 1, 0, "foo","bar");
console.log("arr: ", arr);// []
console.log("obj: ", obj1);// { "0": "c", "1": "foo", "2": "bar", "3": "b", "4": "a", length: 8 }
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].splice.call(obj1, 1, 1, "foo","bar");
console.log("arr: ", arr);// [ "b" ]
console.log("obj: ", obj1);// { "0": "c", "1": "foo", "2": "bar", "3": "a", length: 7 }

splice的行為回歸了,它現(xiàn)在對obj1產(chǎn)生影響,并且是我們預(yù)計的樣子

Array.prototype.every
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].every.call(obj1, function (val) {
  return val === "a" || val === "c"
});
console.log("arr: ", arr);// false
console.log("obj: ", obj1);// { "0": "c", "1": "b", "2": "a", length: 6 }
Array.prototype.filter
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].filter.call(obj1, function (val) {
  return val === "a" || val === "c"
});
console.log("arr: ", arr);// [ "c", "a" ]
console.log("obj: ", obj1);// { "0": "c", "1": "b", "2": "a", length: 6 }
Array.prototype.forEach
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].forEach.call(obj1, function (val) {
  return val + " add";
});
console.log("arr: ", arr);// undefined
console.log("obj: ", obj1);// { "0": "c", "1": "b", "2": "a", length: 6 }
Array.prototype.map
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].map.call(obj1, function (val) {
  return val + " add";
});
console.log("arr: ", arr);// [ "c add", "b add", "a add", , ,  ]
console.log("obj: ", obj1);// { "0": "c", "1": "b", "2": "a", length: 6 }
Array.prototype.reduce
var obj1 = {
  0: "c",
  1: "b",
  2: "a",
  length: 6
}
var arr = [].reduce.call(obj1, function (pre, cur) {
  return pre + " " + cur
});
console.log("arr: ", arr);// "c b a"
console.log("obj: ", obj1);// { "0": "c", "1": "b", "2": "a", length: 6 }

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/82349.html

相關(guān)文章

  • underscore中的小技巧

    摘要:在閱讀的過程中,發(fā)現(xiàn)了它的一些小技巧,對我們平時的編程很有用。事實(shí)上,在上也的確是可以被更改的而在或高版本的中,并不能更改全局的。但是,局部的仍然可以被改變。所以,建議在已知長度的情況下,使用第一種,而不知道長度的情況下,使用第二種。 在閱讀 underscore 的過程中,發(fā)現(xiàn)了它的一些小技巧,對我們平時的編程很有用。在這里向大家介紹一二 void 0 代替 underfined 首...

    lifesimple 評論0 收藏0
  • JavaScript 特殊對象 Array-Like Objects 詳解

    摘要:很簡單,不是數(shù)組,但是有屬性,且屬性值為非負(fù)類型即可。至于屬性的值,給出了一個上限值,其實(shí)是感謝同學(xué)指出,因?yàn)檫@是中能精確表示的最大數(shù)字。如何將函數(shù)的實(shí)際參數(shù)轉(zhuǎn)換成數(shù)組 這篇文章拖了有兩周,今天來跟大家聊聊 JavaScript 中一類特殊的對象 -> Array-Like Objects。 (本文節(jié)選自 underscore 源碼解讀系列文章,完整版請關(guān)注 https://githu...

    zhaofeihao 評論0 收藏0
  • JS中的call、apply、bind方法詳解

    摘要:不能應(yīng)用下的等方法。首先我們可以通過給目標(biāo)函數(shù)指定作用域來簡單實(shí)現(xiàn)方法保存,即調(diào)用方法的目標(biāo)函數(shù)考慮到函數(shù)柯里化的情況,我們可以構(gòu)建一個更加健壯的這次的方法可以綁定對象,也支持在綁定的時候傳參。原因是,在中,多次是無效的。 bind 是返回對應(yīng)函數(shù),便于稍后調(diào)用;apply 、call 則是立即調(diào)用 。 apply、call 在 javascript 中,call 和 apply 都是...

    zombieda 評論0 收藏0
  • JS基礎(chǔ)篇--call、apply、bind方法詳解

    摘要:首先我們可以通過給目標(biāo)函數(shù)指定作用域來簡單實(shí)現(xiàn)方法保存,即調(diào)用方法的目標(biāo)函數(shù)考慮到函數(shù)柯里化的情況,我們可以構(gòu)建一個更加健壯的這次的方法可以綁定對象,也支持在綁定的時候傳參。原因是,在中,多次是無效的。而則會立即執(zhí)行函數(shù)。 bind 是返回對應(yīng)函數(shù),便于稍后調(diào)用;apply 、call 則是立即調(diào)用 。 apply、call 在 javascript 中,call 和 apply 都是...

    lastSeries 評論0 收藏0
  • JavaScript 類數(shù)組對象

    摘要:定義類數(shù)組對象的定義可以通過索引訪問元素,并且擁有屬性沒有數(shù)組的其他方法,例如,,等。所以當(dāng)后面的作用對象是一個類數(shù)組時,就會把這個類數(shù)組對象轉(zhuǎn)換為了一個新的數(shù)組。 定義 JavaScript 類數(shù)組對象的定義: 可以通過索引訪問元素,并且擁有 length 屬性; 沒有數(shù)組的其他方法,例如 push , forEach , indexOf 等。 舉例說明 var foo = {...

    haobowd 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<