js基礎中不熟悉的點

  1. 亦或

給定一個非空整數數組,除了某個元素只出現一次以外,其余每個元素均出現兩次。找出那個只出現了一次的元素。

亦或:如果a,b兩個值相同則亦或為0,如果不同則亦或為1

1 ^ 1 = 0 
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
3 ^ 3 = 0 

for(let i = 1 , len = nums.length;i < len; i ++){
  nums[ 0 ] ^ = nums[ i ]  
}
return nums[0]

? 結題答案中有用map數組比我用for循環計算時間少,why?

可能是網絡延時!!!!

for循環的性能應該是最好的

  1. Array: map forEach

map 和forEach都接受兩個參數,第一個參數必填是個函數,第二個參數選填,作用是改變函數中this指向

var name = 'wky'
var a = { name = "yc" }
var b = [1,3,4]
b.map(function(val,index){
    return val + this.name
}) 
// 輸出 ['1wky','3wky','4wky']

b.map(function(val,index){
    return val + this.name
},a)

//輸出 [ '1yc', '3yc','4yc' ]


// 注:箭頭函數this指向不變,仍指向父級中this指向

b.map(val =>{ return val + this.a },a)

// 輸出輸出 ['1wky','3wky','4wky']

  1. ? undefined == null true

    0 == undefined false

    ''== undefined false

    0 == null false

    '' == null false

詳見末尾寬松相等

  1. 基礎類型

字符串布爾類型都有方法,是因為使用對應的變量時,編譯器會將其裝箱成對應的對象類型,例如 var s = 'test',如果使用s變量時會將s = new String(s)進行封裝,一旦屬性引用結束,這個新創建的對象就會被銷毀

var s = 'test';
s == new String(s)  // true
s.len = 4
s.len   // undefined
  1. arguments 和 function

    1.1 函數形參和實參
    在函數體中存在一個形參的引用,指向當前傳入的實參列表,通過它可以獲得參數的值

    1.2 函數體內this指向
    在嚴格模式中this 指向 undefined

    1.3 arguments

    1. arguments 是指向實參對象的引用
    2. arguments中的數組 與形參是別名的關系
    3. 嚴格模式下 arguments是個保留字,并且不能被重新賦值
    4. 非嚴格模式下 arguments是個標識符, 能被修改
    function test(){ 'use strict'; console.log( arguments ); arguments = 1 }
    
    // 報錯 Uncaught SyntaxError: Unexpected eval or arguments in strict mode
    
    function test(){ arguments =2; console.log( arguments ); arguments = 1 }
    
    // arguments 輸出為2
    

    1.4 閉包

    關聯到閉包的作用域鏈都是活動的,嵌套的函數不會講作用域內的私有成員復制一份,也不會對所綁定的變量生成靜態快照。

    1.5 函數屬性、方法和構造函數

    1. 函數length和函數實際參數的length
    function check(a, b ,c){
        console.log(arguments.length); // 實際參數個數
        console.log(arguments.callee.length); // 函數期待參數個數
    }
    
    
    1. call 和 apply方法

    call 和 apply方法 第一個參數的作用是改變函數體中this的指向,第二個參數是參數,可傳可不傳

        var obj = { 
            test: function(){console.log(this.a)},
            a: '10' 
        }
        var a = 20;
        obj.test.call(null); // 20
        obj.test.call(obj); // 10
        
        Object.prototype.toString.call([]) // 改變的是toString中this的指向
        
    
    

    apply 參數傳入的是個數組,但是會將數組參數和函數形參一一對應

    function testArray(a){ console.log(a) }
    testArray.apply(null,[1,3])
    <!--輸出 1-->
    
    function test(a,b){ console.log(a);console.log(b) }
    test.apply([1,3])
    <!--輸出  1, 3-->
    

    Object.prototype.toString返回數據解析

    當檢測Array實例時, Array.isArray 優于 instanceof,因為Array.isArray能檢測iframes

    var iframe = document.createElement('iframe');
     document.body.appendChild(iframe);
     xArray = window.frames[window.frames.length-1].Array;
     var arr = new xArray(1,2,3); // [1,2,3]
     
     // Correctly checking for Array
     Array.isArray(arr);  // true
     // Considered harmful, because doesn't work though iframes
     arr instanceof Array; // false
    
    1. 第一個參數改變函數內部this指向的函數還有Array類中的方法:

      1. forEach
      2. filter
      3. findIndex
      4. find
      5. map

      reduce 如果在空數組上調用reduce必須給一個默認值不然就會報錯

     const array = [];
     const reducer = (c, a) => c + a ;
     array.reduce(reducer)
     <!--VM1172:1 Uncaught TypeError: Reduce of empty array with no initial value-->
     <!--    at Array.reduce (<anonymous>)-->
     <!--    at <anonymous>:1:7-->
     <!--(anonymous) @ VM1172:1-->
     array.reduce(reducer,0)
     <!--0-->
    

    array.length 值是一個無符號32位整數

    1. bind : 第一個參數改變this指向,第二個是傳入的參數
    2. 構造函數 Function構造函數創建的函數并不使用詞法作用域,相反,函數體代碼的編譯總是會在頂層函數執行.
    function con (){
         const local = 'local';
         return new Function ('return local');
     }
     const local = 'global';
     con()(); // global
     
     function con(){
     var scope1 = 'local';
         return function(){
             console.log( scope1 );
         }
     }
     var scope1 = 'global';
     
     con()(); // 輸出 local
    
  1. promise promise.all await async generator setTimeout

    1. setTimeout (function,delay,param)
    function test(value){ console.log(value) }
    setTimeout(test,500,10) // 500ms之后 輸出10
    // 參數是待執行函數的參數
    
    1. Promise.resolve()

      需要將現有對象轉換為Promise對象

      1. 參數是一個Promise實例
        如果參數是一個Promise實例,那么Promise.resolve將不做任何修改、原封不動的返回這個實例
      2. 參數是一個thenable對象
        thenabel對象是指具有then方法的對象,例如:
      let thenable = {
          then:(resolve,reject)=>{
              return resolve(21);
          }
      }
      

      Promise.resolve()方法將這個對象轉換為Promise對象,并立即執行then方法

      let thenable = {
          then:(resolve,reject)=>{
              return resolve(21);
          }
      }
      let p1 = Promise.resolve(thenable)
      
      1. 參數不是具有then的對象,或者根本不是對象
        返回一個新的promise對象
      2. 不帶有任何參數
        直接返回一個Promise對象
    2. Promise原理(暫時還是有點懵,可能需要在看看?)

    function Promise(fn){
    var state = "pending";
    var value = null;
    var callbacks = [];
    this.then = function(onFulfilled){
    
        return new Promise(function( resolve ){
            handle({
                onFulfilled: onFulfilled || null,
                resolve: resolve
            });
        })
    };
    function handle(callback){
        if( state == 'pending' ){
            callbacks.push(callback);
            return ;
        }
        if(!callback.onFulfilled){
            callback.resolve(value);
            return;
        }
        var ret = callback.onFulfilled(value);
        callback.resolve(ret);
    }
    function resolve(newValue){
        if(newValue && (typeof newValue ==='object' || typeof  newValue ==='function')){
            var then = newValue.then;
            if(typeof then ==='function'){
                then.call(newValue,resolve);
                return;
            }
        }
        state = 'fulfilled';
        value = newValue;
        setTimeout(function(){
            callbacks.forEach(function(callback){
                handle(callback);
            })
        },0);
    }
    fn(resolve);
    }
    
  2. generator 自執行函數

function co(gen){
    var g = gen();
    var t = g.next();
    function next(res){
        console.log(res);
        if(res.done) return ;
        if(typeof g.next !='function') return;
        if(res.value instanceof Promise){
            res.value.then(value =>{
                res = g.next(value);
                next(res);
            })
        }
    }
    next(t)
};

注意: g.next(value) 這個value對應的值是上一個yield的返回值

  1. JSON.stringify 接受三個參數 (value,replace,space)

    1. replace 是函數
    JSON.stringify({name:'name',function(key,value){key // key  value // 值 }})
    
    1. replace是數組
    JSON.stringify({1:1,2:1,3:1,5:1},[1,5]) // "{ "1":1,"5":1 }"
    
  2. for of 只能遍歷存在 Symbol.iterator接口的數據結構,對象不存在這個接口,所以只能通過手動添加這個遍歷器接口

var Obj = { name:'name',age:18 ,info:{ name:'infoName',age:'infoAge' }};
Object.defineProperty(Obj,Symbol.iterator,{
    value:function(){
        var o = this;
        var idx = 0;
        var ks = Object.keys(o);
        return {
            next:function(){
                return {
                    value: o[ks[idx++]],
                    done: idx > ks.length
                }
            }
        }
    },
    enumerabel: false,
    writable: false,
    configurable: true,
    
});
for(let value of Obj){
    console.log(value);
}
// 輸出    name  18    info:{ name:'infoName', age:'infoAge' }
  1. 原型 繼承

    1. Object.create模擬實現
    Object.create = function (o){
        var F = function(){};
        F.prototype = o;
        return new F();
    }
    
  2. 強制類型轉換

    1. JSON.stringify轉換規則(ToString)
    1. 字符串、數字、布爾值和null的轉換規則和ToString一致
    2. 如果傳遞給JSON.stringify的對象中定義了toJSON方法,那么該方法會在字符串化前調用,以便將對象轉化成安全的JSON值
    var a ={ 
        name:'wky',
        age:10,
        toJSON:function(){ 
            return this.name
            } 
    }
    JSON.stringify(a) ;// ""wky""
    
    1. ToNumber

    為了將值轉換為基本數據類型,抽象操作ToPrimitive會先檢查該值是否有valueof()方法,沒有然后在檢查是否有通toString()方法

    var a = { 
        valueOf:function(){ return '23' },
        toString:function(){ return '12' } 
    }
    
    Number(a) // 23
    
    
    1. 寬松相等

      1. 字符串和數字之間相等的比較

      字符串轉換成數字

      '42' == 42 // true Number('42') == 42
      
      
      1. 其他類型和Boolean類型的比較

      boolean類型轉換成number

      '42' == true  // false   '42' == Number(true)1
      
      1. null 與undefined對比 (相等)
      2. 對象與非對象的比較

      ToPrimative(Obj) == 字符串或者數字

      42 == [42] // true
      
      
  3. 如何判斷對象是原生的還是非原生對象

原生對象 執行toString()方法之后函數中會出現'native code'函數

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,054評論 0 2
  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,842評論 2 17
  • 單例模式 適用場景:可能會在場景中使用到對象,但只有一個實例,加載時并不主動創建,需要時才創建 最常見的單例模式,...
    Obeing閱讀 2,104評論 1 10
  • 肯定是我太酷,不然怎么寫出來的東西這么奇怪。
    幸有我來_8e8a閱讀 480評論 0 0
  • 2018-05-20· 字數 593· 閱讀 80· 日記本 姓名:周富強 公司:廈門大科機械有限公司 日精進打卡...
    ZFQ_dacf閱讀 164評論 0 0