- 亦或
給定一個非空整數(shù)數(shù)組减余,除了某個元素只出現(xiàn)一次以外,其余每個元素均出現(xiàn)兩次惩系。找出那個只出現(xiàn)了一次的元素位岔。
亦或:如果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]
堡牡? 結(jié)題答案中有用map數(shù)組比我用for循環(huán)計算時間少抒抬,why?
可能是網(wǎng)絡(luò)延時!N畋2两!!
for循環(huán)的性能應(yīng)該是最好的
- Array: map forEach
map 和forEach都接受兩個參數(shù)芥颈,第一個參數(shù)必填是個函數(shù)惠勒,第二個參數(shù)選填,作用是改變函數(shù)中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' ]
// 注:箭頭函數(shù)this指向不變爬坑,仍指向父級中this指向
b.map(val =>{ return val + this.a },a)
// 輸出輸出 ['1wky','3wky','4wky']
-
纠屋? undefined == null true
0 == undefined false
''== undefined false
0 == null false
'' == null false
詳見末尾寬松相等
- 基礎(chǔ)類型
字符串布爾類型都有方法,是因為使用對應(yīng)的變量時妇垢,編譯器會將其裝箱成對應(yīng)的對象類型巾遭,例如 var s = 'test',如果使用s變量時會將s = new String(s)進(jìn)行封裝肉康,一旦屬性引用結(jié)束闯估,這個新創(chuàng)建的對象就會被銷毀
var s = 'test';
s == new String(s) // true
s.len = 4
s.len // undefined
-
arguments 和 function
1.1 函數(shù)形參和實參
在函數(shù)體中存在一個形參的引用,指向當(dāng)前傳入的實參列表吼和,通過它可以獲得參數(shù)的值1.2 函數(shù)體內(nèi)this指向
在嚴(yán)格模式中this 指向 undefined1.3 arguments
- arguments 是指向?qū)崊ο蟮囊?/li>
- arguments中的數(shù)組 與形參是別名的關(guān)系
- 嚴(yán)格模式下 arguments是個保留字涨薪,并且不能被重新賦值
- 非嚴(yán)格模式下 arguments是個標(biāo)識符, 能被修改
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 閉包
關(guān)聯(lián)到閉包的作用域鏈都是活動的炫乓,嵌套的函數(shù)不會講作用域內(nèi)的私有成員復(fù)制一份刚夺,也不會對所綁定的變量生成靜態(tài)快照献丑。
1.5 函數(shù)屬性、方法和構(gòu)造函數(shù)
- 函數(shù)length和函數(shù)實際參數(shù)的length
function check(a, b ,c){ console.log(arguments.length); // 實際參數(shù)個數(shù) console.log(arguments.callee.length); // 函數(shù)期待參數(shù)個數(shù) }
- call 和 apply方法
call 和 apply方法 第一個參數(shù)的作用是改變函數(shù)體中this的指向侠姑,第二個參數(shù)是參數(shù)创橄,可傳可不傳
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 參數(shù)傳入的是個數(shù)組,但是會將數(shù)組參數(shù)和函數(shù)形參一一對應(yīng)
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-->
當(dāng)檢測Array實例時, Array.isArray 優(yōu)于 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
-
第一個參數(shù)改變函數(shù)內(nèi)部this指向的函數(shù)還有Array類中的方法:
- forEach
- filter
- findIndex
- find
- map
reduce 如果在空數(shù)組上調(diào)用reduce必須給一個默認(rèn)值不然就會報錯
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位整數(shù)
- bind : 第一個參數(shù)改變this指向莽红,第二個是傳入的參數(shù)
- 構(gòu)造函數(shù) Function構(gòu)造函數(shù)創(chuàng)建的函數(shù)并不使用詞法作用域妥畏,相反,函數(shù)體代碼的編譯總是會在頂層函數(shù)執(zhí)行.
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
-
promise promise.all await async generator setTimeout
- setTimeout (function,delay,param)
function test(value){ console.log(value) } setTimeout(test,500,10) // 500ms之后 輸出10 // 參數(shù)是待執(zhí)行函數(shù)的參數(shù)
-
Promise.resolve()
需要將現(xiàn)有對象轉(zhuǎn)換為Promise對象
- 參數(shù)是一個Promise實例
如果參數(shù)是一個Promise實例安吁,那么Promise.resolve將不做任何修改醉蚁、原封不動的返回這個實例 - 參數(shù)是一個thenable對象
thenabel對象是指具有then方法的對象,例如:
let thenable = { then:(resolve,reject)=>{ return resolve(21); } }
Promise.resolve()方法將這個對象轉(zhuǎn)換為Promise對象鬼店,并立即執(zhí)行then方法
let thenable = { then:(resolve,reject)=>{ return resolve(21); } } let p1 = Promise.resolve(thenable)
- 參數(shù)不是具有then的對象网棍,或者根本不是對象
返回一個新的promise對象 - 不帶有任何參數(shù)
直接返回一個Promise對象
- 參數(shù)是一個Promise實例
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); }
generator 自執(zhí)行函數(shù)
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對應(yīng)的值是上一個yield的返回值
-
JSON.stringify 接受三個參數(shù) (value,replace,space)
- replace 是函數(shù)
JSON.stringify({name:'name',function(key,value){key // key value // 值 }})
- replace是數(shù)組
JSON.stringify({1:1,2:1,3:1,5:1},[1,5]) // "{ "1":1,"5":1 }"
for of 只能遍歷存在 Symbol.iterator接口的數(shù)據(jù)結(jié)構(gòu)滥玷,對象不存在這個接口,所以只能通過手動添加這個遍歷器接口
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' }
-
原型 繼承
- Object.create模擬實現(xiàn)
Object.create = function (o){ var F = function(){}; F.prototype = o; return new F(); }
-
強(qiáng)制類型轉(zhuǎn)換
- JSON.stringify轉(zhuǎn)換規(guī)則(ToString)
- 字符串巍棱、數(shù)字罗捎、布爾值和null的轉(zhuǎn)換規(guī)則和ToString一致
- 如果傳遞給JSON.stringify的對象中定義了toJSON方法,那么該方法會在字符串化前調(diào)用拉盾,以便將對象轉(zhuǎn)化成安全的JSON值
var a ={ name:'wky', age:10, toJSON:function(){ return this.name } } JSON.stringify(a) ;// ""wky""
- ToNumber
為了將值轉(zhuǎn)換為基本數(shù)據(jù)類型桨菜,抽象操作ToPrimitive會先檢查該值是否有valueof()方法,沒有然后在檢查是否有通toString()方法
var a = { valueOf:function(){ return '23' }, toString:function(){ return '12' } } Number(a) // 23
-
寬松相等
- 字符串和數(shù)字之間相等的比較
字符串轉(zhuǎn)換成數(shù)字
'42' == 42 // true Number('42') == 42
- 其他類型和Boolean類型的比較
boolean類型轉(zhuǎn)換成number
'42' == true // false '42' == Number(true)1
- null 與undefined對比 (相等)
- 對象與非對象的比較
ToPrimative(Obj) == 字符串或者數(shù)字
42 == [42] // true
如何判斷對象是原生的還是非原生對象
原生對象 執(zhí)行toString()方法之后函數(shù)中會出現(xiàn)'native code'函數(shù)