javascript知識點總結(jié)

1.原型 構(gòu)造函數(shù) 實例

  • 原型(prototype):每當(dāng)定義一個對象(函數(shù)也是對象)的時候,對象都會包含一些預(yù)定義的屬性验游,其中每個函數(shù)對象都包含一個prototype屬性,這個屬性指向函數(shù)的原型對象
  • 構(gòu)造函數(shù):可以通過new 來新建一個對象的函數(shù)
  • 實例:通過構(gòu)造函數(shù)和new創(chuàng)建出來的對象就是實例,實例通過_proto_指向原型碧信,通過constructor指向構(gòu)造函數(shù)
  • 每個對象都有_proto_屬性,但是只有函數(shù)對象才有prototype屬性

例子:
var obj={}等同于 var obj=new Object();
obj是構(gòu)造函數(shù)(Object)的一個實例
obj.prototype就是一個原型對象(obj.prototype==原型對象)
obj._proto_ == Object.prototype
obj.constructor == Object
Object.prototype.constructor == Object

image.png

var person1 = new Person()
1.person1._proto_是什么?
因為person1._proto_ === person1的構(gòu)造函數(shù).prototype
因為person1的構(gòu)造函數(shù) === Person
所以 person1._proto_ === Person.prototype
2.Person._proto_是什么
因為Person._proto_ === Person的構(gòu)造函數(shù).prototype
因為Person的構(gòu)造函數(shù) === Function
所以Person._proto_ ===Function.prototype
3.Person.prototype._proto_是什么?
因為Person.prototype是一個普通的對象街夭,一個普通對象的構(gòu)造函數(shù) ===Object
所以 Person.prototype._proto_ ===Object.prototype
4.Object.prototype._proto_是什么
Object.prototype對象也有_proto_屬性砰碴,但是比較特殊,為null,處于原型鏈的頂端板丽,所以Object.prototype._proto_ ===null

2.原型鏈

原型鏈是由原型對象組成呈枉,每個對象都有_proto_屬性,指向了創(chuàng)建該對象的構(gòu)造函數(shù)和原型埃碱,_proto_將原型對象鏈接起來組成了原型鏈猖辫,是用來實現(xiàn)繼承和共享屬性的有限對象鏈。

  • 屬性查找機制:當(dāng)查找對象屬性時砚殿,如果實例對象自身不存在該屬性啃憎,則沿著原型鏈向上一級查找,找到則輸出似炎,如果沒找到辛萍,則沿著原型鏈繼續(xù)向上查找,直到最頂層原型對象Object.prototype名党,如果還沒有則輸出undefined
  • 屬性修改機制:只會修改實例對象本身的屬性叹阔,如果不存在,則進行添加該屬性传睹,如果需要修改原型的屬性時耳幢,則可以用: b.prototype.x = 2;但是這樣會造成所有繼承于該對象的實例的屬性發(fā)生改變欧啤。

3.函數(shù)柯里化

在一個函數(shù)中睛藻,首先添加幾個固定的參數(shù),在返回一個新的函數(shù)邢隧,稱為函數(shù)的柯里化店印,可以多次重復(fù)調(diào)用。
ES5實現(xiàn)高階函數(shù)也叫函數(shù)的柯里化

function add(x){
    return function(y){
         return x+y
     }
}
var add2= add(2);
add2(3);          // => 5
add(10)(11);        // => 21

ES6箭頭函數(shù)實現(xiàn)函數(shù)柯里化

const add= x=> y=> x+y;

4.閉包

function init() {
    var name = "Mozilla"; // name 是一個被 init 創(chuàng)建的局部變量
    function displayName() { // displayName() 是內(nèi)部函數(shù),一個閉包
        alert(name); // 使用了父函數(shù)中聲明的變量
    }
    displayName();
}
init();

5.對象的深淺拷貝

對象的拷貝在js中比較常見

  • 淺拷貝:僅僅復(fù)制對象的引用倒慧,而不是對象本身按摘,一旦修改拷貝對象包券,原對象也會被修改
  • 深拷貝:把復(fù)制的對象所有引用的對象全部拷貝包括地址,修改拷貝的對象炫贤,原對象不會改變溅固。
1.淺拷貝

淺拷貝的方法比較簡單,只是簡單復(fù)制引用兰珍,,如果我們要復(fù)制對象的屬性不引用類型就可以使用淺拷貝侍郭,
1.簡單的賦值也屬于淺拷貝

var obj = { age: '12',name:'jack' };
var newObj = obj;
//此時將obj中的age屬性值改變,會發(fā)現(xiàn)newObj中的age屬性值跟著改變
obj.age = '13';  //obj: { age: '13' }  newObj: { age: '13',name:''jack}

2.遍歷復(fù)制掠河,返回新對象

function shallowCopy(obj) {
    var copy = {};
    // 只復(fù)制可遍歷的屬性
    for (key in obj) {
        // 只復(fù)制本身擁有的屬性
        if (obj.hasOwnProperty(key)) {
            copy[key] = obj[key];
        }
    }
    return copy;
}

obj.hasOwnProperty() MDN解釋
這個方法可以用來檢測一個對象是否含有特定的自身屬性
語法:obj.hasOwnProperty(prop)
參數(shù):要檢測的屬性 字符串 名稱或者 Symbol
返回值: 用來判斷某個對象是否含有指定的屬性的 Boolean

3.js內(nèi)部的淺拷貝
var newObj = Object.assign({}, originObj);其中第一個參數(shù)是我們最終復(fù)制的目標(biāo)對象亮元,后面的所有參數(shù)是我們的即將復(fù)制的源對象,支持對象或數(shù)組唠摹。
4.數(shù)組的淺拷貝
[].slice();
5.展開運算符
{...a}

2深拷貝

常用的有JSON.parse(),遞歸深拷貝爆捞,還有es5的object.create();
1.JSON.parse()
這種方法不支持json /正則/Data/undefined等
var a = {...}
var b = JSON.parse( JSON.stringify(a) )
2.遞歸深拷貝

function copy(obj1, obj2) {
    var obj = obj2 || {};
    for (var i in obj1) {
        var prop = obj1[i];
 
        // 避免相互引用對象導(dǎo)致死循環(huán),如obj1.a = obj1的情況
        if(prop === obj) {
            continue;
        }
 
        if (typeof prop === 'object') {
            obj[i] = (prop.constructor === Array) ? [] : {};
            arguments.callee(prop, obj[i]);
        } else {
            obj[i] = prop;
        }
    }
    return obj;
}

3.object.create()

function deepClone(obj1, obj2) {
    var obj = obj2|| {};
    for (var i in obj1) {
        var prop = obj1[i];
 
        // 避免相互引用對象導(dǎo)致死循環(huán)勾拉,如obj1.a = obj1的情況
        if(prop === obj) {
            continue;
        }
 
        if (typeof prop === 'object') {
            obj[i] = (prop.constructor === Array) ? prop : Object.create(prop);
        } else {
            obj[i] = prop;
        }
    }
    return obj;
}

6.代碼的復(fù)用

當(dāng)你發(fā)現(xiàn)代碼多次重復(fù)的時候嵌削,應(yīng)該考慮代碼的復(fù)用。

  • 函數(shù)封裝
  • 繼承
  • 復(fù)制extend

7.模塊化

模塊化開發(fā)是現(xiàn)在前端開發(fā)的重要部分望艺,模塊化提高了項目的可維護性和可拓展性、可協(xié)作性肌访,在瀏覽器中ES6支持模塊化找默,在Node中使用commonjs的模塊支持

  • es6 :import /export
  • commonjs:require /module.exports /exports
  • amd: require /defined
    1.require支持動態(tài)導(dǎo)入,import不支持
    2.require是同步導(dǎo)入吼驶,import是異步導(dǎo)入
    3.require是值拷貝惩激,導(dǎo)出值不會影響導(dǎo)入值,import指向內(nèi)存地址蟹演,導(dǎo)入值會隨導(dǎo)出值變化

8.this

1.全局環(huán)境/普通函數(shù)
在全局函數(shù)中风钻,this永遠指向window,普通函數(shù)的調(diào)用,不是構(gòu)造函數(shù)沒有使用new,其中this也是指向window

var a = 1;
function  fen(){
    console.log(this);//window
    console.log(this.a)//1
}
fen();

2.構(gòu)造函數(shù)的this指向
構(gòu)造函數(shù)就是指函數(shù)new出來的一個對象酒请,

function Fen(){
     this.a= 1;
     console.log(this)//Fen{a:1}
}
var foo= new Fen();
console.log(foo.a)//10

如果函數(shù)作為構(gòu)造函數(shù)使用骡技,其中this就代表他new出來的對象,如果直接調(diào)用Fen()函數(shù)羞反,而不是new Fen()布朦,那么Fen()就是普通函數(shù),this還是指向全局window
3.對象方法
如果函數(shù)作為對象的方法時昼窗,那么this指向該對象

var obj = {
    a:1,
    foo:function(){
         console.log(this)//Object
         console.log(this.a)//1
   }
}
obj.foo();

如果在對象方法中定義函數(shù)是趴,

var obj = {
    a:1,
    foo:function(){
       function a(){
          console.log(this)//window
          console.log(this.a)//undefined
    }  
   a();
   }
}
obj.foo();

函數(shù)a雖然在obj.foo內(nèi)部定義,但是依然是一個普通函數(shù),this指向window,如果想調(diào)用變量a.可以把this.保存起來

var obj = {
    a:1,
    foo:function(){
      var that = this
       function a(){
          console.log(that)//{a:1}
          console.log(that.a)//1
    }  
   a();
   }
}
obj.foo();

如果foo函數(shù)不作為對象方法被調(diào)用

var obj = {
    a:1,
    foo:function(){
         console.log(this)//window
         console.log(this.a)//undefined
   }
}
var fn=obj.foo();
fn();

obj.foo被賦值給一個全局變量,并沒有作為obj的一個屬性被調(diào)用澄惊,那么此時this還是指向全局window
4.構(gòu)造函數(shù)prototype屬性

function Foo(){
   this.x=10
}
Foo.prototype.getX = function(){
    console.log(this)//Foo{x:10,getX:function}
    console.log(this.x)//10
}
var foo = new Foo();
foo.getX();

在Foo.prototype.getX函數(shù)中唆途,this指向的foo對象富雅,

5.call/apply/bind
當(dāng)一個函數(shù)被call/apply/bind調(diào)用時,this的值就取傳入的對象的值
6箭頭函數(shù)的this
箭頭函數(shù)本身沒有this肛搬,箭頭函數(shù)的內(nèi)部的this是此法作用域没佑,由上下文確定的

9.函數(shù)節(jié)流/函數(shù)防抖

  • 函數(shù)防抖:當(dāng)調(diào)用一個動作幾秒后才會執(zhí)行動作,若在這幾秒內(nèi)又調(diào)用動作則重新計算時間執(zhí)行函數(shù)(只有最后一次事件被觸發(fā))
  • 函數(shù)節(jié)流:預(yù)先設(shè)置一個執(zhí)行周期滚婉,當(dāng)調(diào)用動作的時刻大于等于執(zhí)行周期則執(zhí)行該動作图筹,然后進入下一個周期(一定時間內(nèi)只觸發(fā)一次)
    都是為了限制函數(shù)得執(zhí)行次數(shù),提高性能

1.防抖

//簡單的理解就是在執(zhí)行函數(shù)之前檢查定時器是否已經(jīng)存在
//如果存在說明之前已經(jīng)觸發(fā)了定時器让腹,需要清除之前的定時器
//再重新生成一次定時器远剩,重新執(zhí)行
function debounce(fn,wait){
      let timer = null;
     let that = this;
      return function(){
           if(timer){
            clearTimeout(timer)
         }else{
          timer=setTimeout(()=>{
                fn.call(that,arguments)
//arguments 是類數(shù)組,指傳入函數(shù)的參數(shù)
             },wait)
         }
     }
}
function fn(){
     console.log(1)
}
debounce(fn,1000);

/**
 * @desc 函數(shù)防抖
 * @param func 函數(shù)
 * @param wait 延遲執(zhí)行毫秒數(shù)
 * @param immediate true 表立即執(zhí)行骇窍,false 表非立即執(zhí)行  第一次是否立刻觸發(fā)
 */
function debounce(func,wait,immediate) {
    var timeout;

    return function () {
        var context = this;
        var args = arguments;

        if (timeout) clearTimeout(timeout);
        if (immediate) {
            var callNow = !timeout;
//記錄timeout是否為空瓜晤,第一次為空所以為true,下面的判斷會立即執(zhí)行腹纳,等待防抖的時間timeout會被再次重置為空痢掠,如果在這個時間范圍內(nèi),callNow會為false,所以不會執(zhí)行下面的判斷

            timeout = setTimeout(function(){
                timeout = null;
            }, wait)
            if (callNow) func.apply(context, args)
        }
        else {
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
    }
}

2.節(jié)流

// 簡單的說就是再一個時間范圍執(zhí)行一次嘲恍,不論這個范圍內(nèi)觸發(fā)多少次足画,只執(zhí)行一次
function throttle (fn,delay){
    var timer = null;
    var startTime = Date.now();
    return function(){
       var endTime = Date.now();
       var remaining = delay - (endTime - startTime);
       var context = this;
       var args = arguments;
       clearTimeout(timer);
      if(remaining<=0){
          fn.apply(context,args);
          startTime = Date.now();
       }else{
      timer = setTimeout(fn,remaining)
     }
    }
}
function  fn(){
    console.log(1)
}
throttle(fn,1000)

10.如何使用正則實現(xiàn)trim()?

function trim(string){
   return string.replace(/^\s + | \s + $/g," ")
}

11.手寫AJAX

var xhr = new XMLHttpRequest();
xhr.open('GET',"/XXXX");
xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){
       console.log('請求完成')
       if(xhr.response.status>=200 && xhr.response.status<=300){
                console.log(' 請求成功')
                console.log(xhr.responseText)
            }else{
             
           }
     }
}

12.數(shù)組去重

function fn (arr){
    var temp =[];
     for(var i =0;i<arr.length;i++){
            if(temp.indexOf(arr[i] )== -1){
                 temp.push(arr[i])
             }
         }
    return temp
}
fn(arrr)

es6去重

Array.from(new Set(arrr))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佃牛,一起剝皮案震驚了整個濱河市淹辞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俘侠,老刑警劉巖象缀,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異爷速,居然都是意外死亡央星,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門惫东,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莉给,“玉大人,你說我怎么就攤上這事凿蒜〗” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵废封,是天一觀的道長州泊。 經(jīng)常有香客問我,道長漂洋,這世上最難降的妖魔是什么遥皂? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任力喷,我火速辦了婚禮,結(jié)果婚禮上演训,老公的妹妹穿的比我還像新娘弟孟。我一直安慰自己,他們只是感情好样悟,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布拂募。 她就那樣靜靜地躺著,像睡著了一般窟她。 火紅的嫁衣襯著肌膚如雪陈症。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天震糖,我揣著相機與錄音录肯,去河邊找鬼。 笑死吊说,一個胖子當(dāng)著我的面吹牛论咏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颁井,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼厅贪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了雅宾?” 一聲冷哼從身側(cè)響起卦溢,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秀又,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贬芥,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡吐辙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蘸劈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昏苏。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖威沫,靈堂內(nèi)的尸體忽然破棺而出贤惯,到底是詐尸還是另有隱情,我是刑警寧澤棒掠,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布孵构,位于F島的核電站,受9級特大地震影響烟很,放射性物質(zhì)發(fā)生泄漏颈墅。R本人自食惡果不足惜蜡镶,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恤筛。 院中可真熱鬧官还,春花似錦、人聲如沸毒坛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煎殷。三九已至屯伞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝌数,已是汗流浹背愕掏。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顶伞,地道東北人饵撑。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像唆貌,于是被迫代替她去往敵國和親滑潘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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