Js學(xué)習(xí)總結(jié)

1.重繪和重排問(wèn)題

2.add(2,3)和add(2)(3)問(wèn)題(再考慮他的拓展性拓展),其實(shí)是考察js函數(shù)柯里化問(wèn)題。

curry 的概念很簡(jiǎn)單:只傳遞給函數(shù)一部分參數(shù)來(lái)調(diào)用它涉兽,讓它返回一個(gè)函數(shù)去處理剩下的參數(shù)。

function add1(a){
  var sum=a
  var tmp=function(b){
      sum= sum+ b;
      return tmp;
  }

  tmp.valueOf=function(){
    return sum;
  }

  return tmp;
}
var result=add1(2)(3)(4)(5)(6);
console.log('%d',result);  //輸出14 '%d'會(huì)把result轉(zhuǎn)換為10進(jìn)制痊臭,從而觸發(fā)tmp的valueOf函數(shù)

因?yàn)榈阶詈髏mp(6)之后厂画,返回的是個(gè)tmp,如果輸出tmp
的話稚茅,打印的是tmp這個(gè)函數(shù)對(duì)象纸淮,如下:

console.log(result) :
{ [Function: tmp] valueOf: [Function] }

所以我們要把result轉(zhuǎn)換為10進(jìn)制,console.log('%d',result);
'%d'會(huì)把result轉(zhuǎn)換為10進(jìn)制,從而觸發(fā)tmp的valueOf函數(shù)亚享,輸出sum

還有一種方法是利用ES6語(yǔ)法中的Proxy咽块,這個(gè)方法是我在StackOverflow上看到的

function add(n) {
  sum = n;
  const proxy = new Proxy(function a() {}, {
    get (obj, key) {
      return () => sum;
    },
    apply (receiver, ...args) {
    sum += args[1][0];
    return proxy;
  }
});
  return proxy
}
console.log(add(1)(2)(3));  //6
console.log(add(1)(2)(3)(4)(5)(6));   //21

proxy可以理解是對(duì)目標(biāo)對(duì)象進(jìn)行代理,外界對(duì)該對(duì)象的訪問(wèn)虹蒋,都必須先通過(guò)這層攔截糜芳。
ES6 原生提供 Proxy 構(gòu)造函數(shù),用來(lái)生成 Proxy 實(shí)例魄衅。

var proxy = new Proxy(target, handler);

Proxy 對(duì)象的所有用法峭竣,都是上面這種形式,不同的只是handler參數(shù)的寫(xiě)法晃虫。其中皆撩,new Proxy()表示生成一個(gè)Proxy實(shí)例,target參數(shù)表示所要攔截的目標(biāo)對(duì)象哲银,handler參數(shù)也是一個(gè)對(duì)象扛吞,用來(lái)定制攔截行為。上面的代碼就主要用到了proxy的get 和 apply

具體Proxy的使用可以學(xué)習(xí)阮一峰的ECMAScript 6 入門(mén)

其實(shí)我在看完P(guān)roxy和他的用法之后荆责,并不知道proxy有什么優(yōu)勢(shì)滥比,只覺(jué)得它是另一種方法,而且有點(diǎn)難理解做院∶し海可能是我還不知道proxy的優(yōu)勢(shì)吧。

3.ES6中箭頭函數(shù)和普通函數(shù)的區(qū)別键耕。

1.this的區(qū)別寺滚。普通函數(shù)如果是作為對(duì)象的方法被調(diào)用的,則其 this 指向了那個(gè)調(diào)用它的對(duì)象;但是箭頭函數(shù)的則會(huì)捕獲其所在上下文的 this 值屈雄,作為自己的 this 值村视。箭頭函數(shù)需要記著這句話:“箭頭函數(shù)中沒(méi)有 this 綁定,必須通過(guò)查找作用域鏈來(lái)決定其值酒奶,如果箭頭函數(shù)被非箭頭函數(shù)包含蚁孔,則 this 綁定的是最近一層非箭頭函數(shù)的 this.

var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b(); // prints undefined, Window
obj.c(); // prints 10, Object {...}

2.箭頭函數(shù)不綁定arguments,取而代之用rest參數(shù) … 解決 (rest參數(shù)介紹

function consol() {
  console.log(arguments)
}
consol('haha',1)  // { '0': 'haha', '1': 1 }

var conso = (...args)=>{ console.log(args)}
conso('hahaha',1)   // [ 'hahaha', 1 ]

4.javascript閉包問(wèn)題奶赔。在網(wǎng)上看了很多關(guān)于對(duì)于什么是閉包的解釋。

看過(guò)一個(gè)答案勒虾,我覺(jué)得挺通俗易懂的纺阔。

閉包 就是把函數(shù)以及其所依賴的所有外部自由變量保存在一起的結(jié)合體
閉包 就是一個(gè)函數(shù)把外部的那些不屬于自己的對(duì)象也包含(閉合)進(jìn)來(lái)了。

參見(jiàn):如何通俗易懂的理解閉包
閉包的牛逼解答

這兩者都很好理解修然〉讯郏看一段代碼:

var foo = function(){
    var name = "exe";
    return function inner(){
        console.log( name );
    }
}
var bar = foo();//這里雖然得到的是函數(shù)inner的引用,而不是那一坨代碼
bar();//這里開(kāi)始執(zhí)行inner函數(shù)  "exe"  讀取foo函數(shù)內(nèi)部的變量

這里面的 name 就是相對(duì)于函數(shù) inner( )的外部自由變量愕宋。所以inner函數(shù)就是一個(gè)閉包玻靡。

閉包的作用

它的最大用處有兩個(gè),一個(gè)是前面提到的可以讀取函數(shù)內(nèi)部的變量中贝,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中囤捻。(因?yàn)殚]包引用了上一級(jí)的環(huán)境,所以導(dǎo)致上一級(jí)也釋放不了邻寿。拿上例來(lái)說(shuō)蝎土,inner()函數(shù)引用name,而這個(gè)name是上一級(jí)的變量。這導(dǎo)致inner始終在內(nèi)存中绣否,而inner的存在依賴于foo誊涯,因此foo也始終在內(nèi)存中,不會(huì)在調(diào)用結(jié)束后蒜撮,被垃圾回收機(jī)制回收暴构。

閉包的原理(為什么能夠訪問(wèn)外部的自由變量)

其實(shí)就是作用域鏈。關(guān)于作用域?qū)ο蠹白饔糜蜴湹闹v解:
推薦一篇博客: JavaScript閉包的底層運(yùn)行機(jī)制

最后:
閉包是什么時(shí)候被創(chuàng)建的段磨?因?yàn)樗蠮avaScript對(duì)象都是閉包取逾,因此,當(dāng)你定義一個(gè)函數(shù)的時(shí)候苹支,你就定義了一個(gè)閉包砾隅。
閉包是什么時(shí)候被銷(xiāo)毀的?當(dāng)它不被任何其他的對(duì)象引用的時(shí)候债蜜。

5.實(shí)現(xiàn)數(shù)組扁平化處理琉用。

一種方法是用遞歸的方式。

var arr = [1, [2, [3, 4]]];

function flatten(arr) {
    var result = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flatten(arr[i]))
        }
        else {
            result.push(arr[i])
        }
    }
    return result;
}


console.log(flatten(arr))

另一種是用ES6的擴(kuò)展運(yùn)算符 ...
擴(kuò)展運(yùn)算符 ... 可以把一個(gè)數(shù)組轉(zhuǎn)換為參數(shù)序列

var arr = [1, [2, [3, 4]]];
console.log(...arr)   // ...運(yùn)算符把數(shù)組arr 轉(zhuǎn)換為  1  [2,[3,4]] 兩個(gè)參數(shù)

再用

arr = [].contact(...arr)  //  [1,2,[3,4]  

這樣就去掉了數(shù)組的一層 順著這個(gè)方法一直繼續(xù)下去策幼,就寫(xiě)出了如下代碼

function flatten(arr) {
   while (arr.some(item => Array.isArray(item))) { //some函數(shù)會(huì)對(duì)每一個(gè)數(shù)組元素執(zhí)行一次箭頭函數(shù)
    var arr = [].concat(...arr);
  }
   return arr;
}
console.log(flatten(arr))

中間可以輸出一下函數(shù)執(zhí)行的過(guò)程。

1 [ 2, [ 3, [ 4, 5 ] ] ]
[ 1, 2, [ 3, [ 4, 5 ] ] ]
1 2 [ 3, [ 4, 5 ] ]
[ 1, 2, 3, [ 4, 5 ] ]
1 2 3 [ 4, 5 ]
[ 1, 2, 3, 4, 5 ]

奇數(shù)行是...arr 的執(zhí)行結(jié)果
偶數(shù)行是[].concat(...arr); 的執(zhí)行結(jié)果

6.es6和es5中的繼承

ES5繼承

es5的繼承實(shí)際上是用原型鏈實(shí)現(xiàn)的奴紧,將子類的原型設(shè)置為父類的實(shí)例特姐,從而實(shí)現(xiàn)繼承

function father(){
  this.flag = true;
}
function child(){
  this.childFlag = false;
}
// 將子類的prototype對(duì)象指向父類的實(shí)例,實(shí)現(xiàn)繼承
child.prototype = new father();
var child1 = new child();

console.log(child1.__proto__ === child.prototype)  // true
_proto_和protoType的區(qū)別.jpg

這張圖好像是我在知乎上看到的。

ES6繼承

es6繼承就很容易理解了黍氮,差不多就是java的class
詳細(xì)學(xué)習(xí)可以看阮一峰的ES6入門(mén)

7.數(shù)組去重

indexOf

var array = [1, 1, '1'];

function unique(array) {
   var res = [];
   for (var i = 0, len = array.length; i < len; i++) {
       var current = array[i];
       if (res.indexOf(current) === -1) {
           res.push(current)
       }
   }
   return res;
}

console.log(unique(array));

由于indexOf是一個(gè)一個(gè)進(jìn)行比較唐含,效率不高浅浮。
可以先對(duì)數(shù)組進(jìn)行排序,排序后,相同的值就會(huì)被排在一起捷枯,然后我們就可以只判斷當(dāng)前元素與上一個(gè)元素是否相同滚秩,相同就說(shuō)明重復(fù),不相同就添加進(jìn) res淮捆。這種方法效率高于使用 indexOf郁油。

8.淺拷貝和深拷貝

淺拷貝

對(duì)于數(shù)組和對(duì)象這種屬于引用類型的,如果淺拷貝(例如用 = 直接賦值,或者只遍歷第一層 )那么對(duì)于復(fù)雜的攀痊,具有嵌套結(jié)構(gòu)的數(shù)據(jù)來(lái)說(shuō)桐腌,淺拷貝只是拷貝了同一個(gè)引用,而這個(gè)引用指向存儲(chǔ)在堆中的一個(gè)對(duì)象苟径“刚荆拷貝完成后,兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象棘街,如果改變其中一個(gè)變量蟆盐,就會(huì)影響另一個(gè)變量。

// 引用類型值復(fù)制
var object1 = {a: 1};
var object2 = object1;
object1.a = 2
console.log(object1)   //  { a: 2 }
console.log(object2)   //  { a: 2 }

可以看出來(lái)遭殉,改變其中一個(gè)變量石挂,另一個(gè)也會(huì)改變

深拷貝

第一種方法:使用 JSON.stringify 和 JSON.parse 方法

var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]
var new_arr = JSON.parse( JSON.stringify(arr));
console.log(new_arr);   //  [ 'old', 1, true, [ 'old1', 'old2' ], { old: 1 } ]

但是這種方法有一個(gè)問(wèn)題,不能拷貝函數(shù)恩沽。

第二種方法誊稚。利用遞歸

function deepClone(source) {
  // 遞歸終止條件
  if (!source || typeof source !== 'object') {
    return source;
  }
  var targetObj = source instanceof Array ? [] : {};
  for (var key in source) {
    if (source.hasOwnProperty(key)){
      if (source[key] && typeof source[key] === 'object') {  //數(shù)組 typeof的結(jié)果也是object
        targetObj[key] = deepClone(source[key]);
      } else {
        targetObj[key] = source[key];
      }
    }
  }
  return targetObj;
}
var object1 = {'year':12, arr: [1, 2, 3], obj: {key: 'value' }, func: function(){return 1;}};
var object2 = [1,[2,[3,4,[5,6]]]]
var newObj= deepClone(object1);
var newObj2 = deepClone(object2)
console.log(newObj)  // { year: 12,arr: [ 1, 2, 3 ],obj: { key: 'value' }, func: [Function: func] }
console.log(newObj2) // [ 1, [ 2, [ 3, 4, [Array] ] ] ]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市罗心,隨后出現(xiàn)的幾起案子里伯,更是在濱河造成了極大的恐慌,老刑警劉巖渤闷,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疾瓮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡飒箭,警方通過(guò)查閱死者的電腦和手機(jī)狼电,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)弦蹂,“玉大人肩碟,你說(shuō)我怎么就攤上這事⊥勾唬” “怎么了削祈?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我髓抑,道長(zhǎng)咙崎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任吨拍,我火速辦了婚禮褪猛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘羹饰。我一直安慰自己伊滋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布严里。 她就那樣靜靜地躺著新啼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刹碾。 梳的紋絲不亂的頭發(fā)上燥撞,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音迷帜,去河邊找鬼物舒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛戏锹,可吹牛的內(nèi)容都是我干的冠胯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锦针,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荠察!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起奈搜,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悉盆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后馋吗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體焕盟,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年宏粤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脚翘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绍哎,死狀恐怖来农,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崇堰,我是刑警寧澤备图,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響揽涮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饿肺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一蒋困、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敬辣,春花似錦雪标、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至撰茎,卻和暖如春嵌牺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背龄糊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工逆粹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人炫惩。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓僻弹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親他嚷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蹋绽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容