工作中积累的问题、知识点总结100题(21-40)

21.非匿名自执行函数

  1.函数名只读

// b 打印的值是什么
var b = 10;
(function b(){
    b = 20;
    console.log(b)
})()

 

解析:

- 如标题一样,非匿名自执行函数,函数名不可以修改,严格模式下会TypeError,
- 非严格模式下,不报错,修改也没有用。
- 查找变量b时,立即执行函数会有内部作用域,会先去查找是否有b变量的声明,有的话,直接复制
- 确实发现具名函数Function b(){} 所以就拿来做b的值
- IIFE的函数内部无法进行复制(类似于const)

 

打印结果为:Function b

  2.

//  打印的值
var b = 10;
(function b(){
    var b = 20;
    console.log(window.b)
    console.log(b)
})()

 

输出:
10
20

  3.

  var b = 10;
  (function b(){
      console.log(b)
      b = 5
      console.log(window.b)
      var b = 20
      console.log(b)
  })()

 

22.变量提升(21.10.22 更新)

var name = 'World!';
(function () {
    if (typeof name === 'undefined') {
        var name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

上面得代码相当于

var name = 'World!';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

 

  2.看下第二个示例

var str = 'World!';   
(function (name) {
    if (typeof name === 'undefined') {
        var name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})(str);




//Hello World 因为name已经变成函数内局部变量

 

23.Switch (2021/10/27)

// 写一个方法

function showCase(value) {
    switch(value) {
    case 'A':
        console.log('Case A');
        break;
    case 'B':
        console.log('Case B');
        break;
    case undefined:
        console.log('undefined');
        break;
    default:
        console.log('Do not know!');
    }
}

  1.

showCase(new String('A'))


// 答案是 'Do not know'


解析: switch 是严格比较,String 实例 和 字符串不一样
        所以一般情况下,写switch语句的时候,都建议写 default

  2.


showCase(String('A')) 答案: Case A String('A') 就是返回一个字符串

 

24, %运算符

function isOdd(num) {
    return num % 2 == 1;
}
function isEven(num) {
    return num % 2 == 0;
}
function isSane(num) {
    return isEven(num) || isOdd(num);
}
var values = [7, 4, '13', -9, Infinity];
values.map(isSane);
 答案:
 
    [true, true, true, false, false]
  解析:
    % 如果不是数值会调用 Number() 去转化
    
        '13'%2    // 1
        Infinity%2    // NaN,Infinity 是无穷大
        -9%2        // -1
        9%-2        // 1,余数的正负号随第一个操作数

      余数和被除数同号

      14 ÷ -3 = -4 ··· 2

      -14 ÷ -3 = 4 ··· -2

      -14 ÷ 3 = -4 ··· -2

     
      -14 ÷ 3 = -4...-2 (余数符号和被除数符号必须相同)
      
    详情解析查看:https://blog.csdn.net/qq_34115899/article/details/79683041

 

25.运算

   1.数组的原型

    Array.isArray(Array.prototype);

    答案:true

    Array。prototype是一个数组,数组的原型是数组,对象的原型是对象,函数的原型是函数

  2.==

    [] == []

    答案:false

    两个引用类型,== 比较的是引用地址

  3. == 和 ! 优先级

  [] == ![]

    答案:true

    ! 优先级高于 == ,右边Boolean([])是true,取返等于false

    一个引用类型和一个值去比较,把引用类型转化成值类型,左边为0

    所以是在比较 0 == false   答案 true

    

  4.加减运算符,字符串与数字

    '5' + 3
    '5' - 3

    答案: 53   2

    加号有拼接功能,减号是逻辑运算

    巩固: typeof(+'1') // ’number' , 对非数值+-常被用来做类型转换,相当于Number()

    1 + - + + + + - + 1   // 2 , + - 又是一元加减操作符号,数学中的正负号,负负得正。

  5.

        var ary = Array(4);
        ary[0] = 22;
     ary[3] = 2323; ary.map(i=>'1')

    答案:['1', empty * 2, '1']

    虽然ary的长度为3,但是存在两个没有内容的,array 上的操作会跳过这些

   6.数组比较大小

    var a = [1, 2, 3];
    var b = [1, 2, 3];
    var c = [1, 2, 3];

    a == b;
    a === b;
    a > c;
    a < c;

  答案:false  false  false  true

    相等(==)和全等(===)比较的是引用地址,引用间的大小比较是按照字典序比较,先比较第一项,再比第二项...

  7.三元运算符的优先级

   // 计算打印结果 
  var val = 'zhangning';
  console.log('Value is ' + (val === 'zhangning') ? 'aaaaa' : 'bbbbb');

  答案:aaaaa

    字符串拼接比三目运算有更高的优先级

    题意为:'Value is true' ? 'aaaaa' : 'bbbbb'

    而不是:'Value is' + (true ? 'aaaaa' : 'bbbbb')

 

26.querySelectorAll 和 getElementsByClassName哪个性能好

   返回的都是nodeList集合

  1.getElementsByClassName 兼容IE9以上,是动态查询的过程,会随着dom结构的变化,得到的节点列表也会发生变化

<div class="wrap">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
</div>
<script>
    var block=document.getElementsByClassName("block");
    var wrap=document.getElementsByClassName("wrap")[0];
    for(var i=0;i<block.length;i++){
        block[i].style.backgroundColor="red";
    }
</script>

  得到三个红色div;

 

 

当改变第二个div的类名时

<div class="wrap">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
</div>
<script>
    var block=document.getElementsByClassName("block");
    var wrap=document.getElementsByClassName("wrap")[0];
    block[1].className="b";
    for(var i=0;i<block.length;i++){
        block[i].style.backgroundColor="red";
    }
</script>

  得到两个红色div,如图

 

 结论:随着dom结构改变,getElementsByClassName 可以动态获取节点列表

 

  2.querySelectorAll 时css3、h5中新增的选择器,兼容IE8及以上,得到的是静态列表,他不会对dom结构进行动态查询,也就是说不是实时的

<div class="wrap">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
</div>
<script>
    var block=document.querySelectorAll(".block");
    var wrap=document.getElementsByClassName("wrap")[0];
    for(var i=0;i<block.length;i++){
        block[i].style.backgroundColor="red";
    }
</script>

  得到三个红色div

 

<div class="wrap">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
</div>
<script>
    var block=document.querySelectorAll(".block");
    var wrap=document.getElementsByClassName("wrap")[0];
    block[1].className="b";
    for(var i=0;i<block.length;i++){
        block[i].style.backgroundColor="red";
    }
</script>

  虽然改变了第二个div的class,但是得到的依然是三个红色的div

 

  区别:就是querySelectorAll的实现类似于一组元素的快照,而并非对文档结构进行搜索的动态查询,所谓快照就是把某个时刻dom中的结构记录下来,而不是通过查询dom结构动态获取,这样实现可以避免使用NodeList对象通常会引起的大多数性能问题。但是也有弊端,如果dom结构发生变化,选择器可能获取不到正确的nodeList。

 

27.Object.create(null) 创建对象没有原型

  1.先看下 {}与Object.create(null)的区别

    通过{} 创建的对象如下

      

 

     通过Object.create(null)创建如下

      

 

     1.通过字面量的方式定义对象原型指向Object.prototype,也就是obj._proto_ === Object.prototype,同时包含了toString,hasOwnProperty等方法

    2.通过Object.create(null)创建出来的对象是一个干净对象,除自身属性外,没有附加其他属性

 

    注:在Vue框架源码中,作者使用大量的Object.create(null) 来创建空对象。

      1.通过Object.create(null) 创建出来的对象,没有任何属性,显示 No properties 。我们可以将其当成一个干净的 map 来使用,自主定义 toString, hasOwnProperty等方法

      2.{...} 创建的对象,使用 for in 遍历对象的时候,会遍历原型链上的属性,带来性能上的损耗。

 

28.对数值和布尔类型结构

  1.数值结构:等号左边的变量放在大括号中进行结构,可以获取到数组包装器结构函数原型中指定的方法。

    let {valueOf} = 12; // [Function: valueOf]

  2.布尔类型解构:等号左边的变量放在大括号中进行解构,可以获取到布尔包装器构造函数原型中指定的方法

    let {valueOf} = false;// [Function: valueOf]

 

posted @ 2021-10-22 13:53  张_Ning  阅读(45)  评论(0编辑  收藏  举报