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])
    
    
    function test(a,b){ console.log(a);console.log(b) }
    test.apply([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)
     
     
     
     
     array.reduce(reducer,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'函数

你可能感兴趣的:(js基础中不熟悉的点)