JS相关

基础类型有哪些?

基本类型有七种

  1. null
  2. undefined
  3. boolean
  4. number
  5. string
  6. symbol(较新标准)
  7. BigInt(新标准)

NaN 也属于 number 类型,并且 NaN 不等于自身;

基础类型的特性是什么?

  1. 基本类型的值是保存在栈内存中的简单数据段
  2. 基础类型是不可变的
    • 即不能强行修改:Array.prototype.sort.call('abc');(会报错)
  3. 基础类型上没有__proto__没有属性

怎么检测基础类型?

    1. 检测基础类型可以用 typeof,但是 typeof null === 'object'
      • null 是基础类型,不是 Object
      • 由于null的历史遗留问题(前三位为000),所以使用typeof检测null会产生BUG
          // 借鉴 Vue 源码的 object 检测方法
          function isObject (obj: any): Boolean {
              return obj !== null && typeof obj === 'object'
          }
      复制代码
    2. 通过 Object.prototype.toString.call (万能方法)
      • 检测 [[class]]
      • 在不覆盖 toString 方法前提下,任何一个对象调用 Object 原生的 toString 方法都会返回 [object type]
          // 借鉴 Vue 源码的检测方法
      
          let _toString = Object.prototype.toString;
      
          function toRawType (value: any): String {
              // 获取 从第九个到倒数第二个 字符
              // 比如 [object String]  获取 String
              return _toString.call(value).slice(8, -1)
          }

基础类型是如何转换的?

  1. 基本类型转换时,首先会调用 valueOf,然后调用 toString。(这两个方法可以被重写)
  2. 在四则运算中,除了 + 其他操作都会以数字进行计算,如果是 + 运算,如果不是所有字面量都是number(都是number就是数字的加法咯),那么会转换为字符串(toString)进行拼接

  3. 那么怎么解决 JS 的精确度问题?

    1. 目前主流的解决方案是 先乘再除
      • 比如精确到小数点后2位
      • 先把需要计算的数字都 乘1000
      • 计算完成后再把结果 除1000
    2. 使用新基础类型 BigInt (兼容性很差)

JS的"真"值有哪些?

JS中除了 "假" 值以外就是 "真" 值。

"假"值包括 7 个

  1. undefined
  2. null
  3. false
  4. NaN
  5. ''
  6. 0
  7. -0

在条件判断的隐式转换中:"假" 值会转换为 false,"真" 值会转换为 true;

怎么检测引用类型?

  1. 通过 Object.prototype.toString.call 检测 [[class]]
  2. 通过 instanceof 判断引用类型
  3. 通过 constructor 判断引用类型(constructor是可写的,慎用)

instanceof 的原理是什么?

instanceof 内部机制是通过判断对象的原型链中是不是能找到对应的的prototype

[] == ![] 结果是什么?

PS: 感谢 @沉末_ 的补充

类型转换都是先 valueOftoString;

右边

  1. 由于 ! 优先级比 == 高,先执行 !
  2. ![] 得到 false
  3. 进行 相等性判断
  4. false 转化为数字 0

左边

  1. 执行 [].valueOf() 原始值 还是 []
  2. 执行 [].toString() 得到 ''
  3. '' 转化为数字 0

所以:0 == 0 ,答案是 true

如何让 (a == 1 && a == 2)条件成立?

依然是类型转换逻辑:基础类型通过 valueOf 进行隐式转换

更改 valueOf 方法就可以实现

    let a = {
        value: 0,
        valueOf: function() {
            this.value++;
            return this.value;
        }
    };
    console.log(a == 1 && a == 2);
 

7. IE和DOM事件流的区别

1.执行顺序不一样
事件流的区别 

IE采用冒泡型事件 Netscape使用捕获型事件 DOM使用先捕获后冒泡型事件 
示例: 
<body> 
<div> 
<button>点击这里</button> 
</div> 
</body> 

冒泡型事件模型: button->div->body (IE事件流) 

捕获型事件模型: body->div->button (Netscape事件流) 

DOM事件模型: body->div->button->button->div->body (先捕获后冒泡) 

2.参数不一样 低版本ie没有回调函数,只能进行冒泡

3.第一个参数是否加"on",低版本IE不支持addEventListener(),支持attachEvent,第一个参数需要加"on"

 

element.addEventListener('click', observer, useCapture);
addEventListener方法接受三个参数。第一个参数是事件名称,值得注意的是,这里事件名称与IE
的不同,事件名称是没’on’开头的;第二个参数observer是回调处理函数;第三个参数注明该处理回调
函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用
2.事件侦听函数的区别 

IE使用: 
[Object].attachEvent("name_of_event_handler", fnHandler); //绑定函数 
[Object].detachEvent("name_of_event_handler", fnHandler); //移除绑定 

DOM使用: 
[Object].addEventListener("name_of_event", fnHandler, bCapture); //绑定函数 
[Object].removeEventListener("name_of_event", fnHandler, bCapture); //移除绑定 

bCapture参数用于设置事件绑定的阶段,true为捕获阶段,false为冒泡阶段。

4.this指向问题,IE指向windows,不指向触发的函数

element.attachEvent('onclick', observer);
attachEvent接受两个参数。第一个参数是事件名称,第二个参数observer是回调处理函数。这里得
说明一下,有个经常会出错的地方,IE下利用attachEvent注册的处理函数调用时this指向不再是先
前注册事件的元素,这时的this为window对象了

9. call apply bind

改变this的指向,

call函数的功能就是把当前的this指向作为函数来执行,并且该函数的this指向传入call的参数

call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。
var Pet = {
        words : '...',
        speak : function (say) {
            console.log(say + ''+ this.words)
        }
    }
    Pet.speak('Speak'); // 结果:Speak...
    var Dog = {
        words:'Wang'
    }                   //将this的指向改变成了Dog
    Pet.speak.call(Dog, 'Speak'); //Pet.speak('Speak')结果: SpeakWang
this 指向所属的对象
这里的this指向必须是引用类型。
如果this被强行改变为值类型,那么能够转为对应包装类型的都会转,不能转的 指向window
设置方法的调用对象(方法的this)时用;

需要注意的是两者传参方式不同:

call():参数直接传入
apply():数组格式传入
原文地址:https://www.cnblogs.com/xiaolucky/p/12083765.html