JS基础知识点(一)

时间:2020-04-22
本文章向大家介绍JS基础知识点(一),主要包括JS基础知识点(一)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

原始类型

  • null

  • undefined

  • boolean

  • number

  • string

  • symbol

注意

  • 原始类型存储的都是值,是没有函数可以调用的,但实际上除null和undefined外,其他类型使用函数时会被转成对应的对象类型,从而可以使用其对象类型原型链上的方法。

  • 虽然typeof null输出object,但它不是对象类型,只是一个历史悠久的bug,在JS的最初版本中使用的是32位系统,为了性能考虑使用低位存储变量的类型信息,000开头代表是对象,然而null表示为全零,所以将它错误的判断为object

对象类型

在js中,除了原始类型,其他的都是对象类型了。对象类型和原始类型不同的是,原始类型存储的是值,对象类型存储的是地址(指针)。

const a = []  //常量a来说,假设内存地址(指针)为#001,那么在地址#001的位置存放了值[],常量a存放了地址(指针)#001
const b = a   //当我们将变量赋值给另外一个变量时,复制的是原本变量的地址(指针),也就是说当前变量b存放的地址(指针)也是#001
b.push(1)     //当我们进行数据修改的时候,就会修改存放在地址(指针)#001上的值,也就导致了两个变量的值都发生了改变。

类型转换

在 JS 中类型转换只有三种情况,分别是:

  • 转换为布尔值

  • 转换为数字

  • 转换为字符串

注意:图中有一个错误,Boolean转字符串这行仅值true转字符串的例子,不是说 Boolean、函数、Symblo转字符串都是true

转Boolean

在条件判断时,除了undefinednullfalseNaN,'',0-0,其他所有值都转为true,包括所有对象。

对象转原始类型

对象在转换类型的时候,会调用内置的 [[ToPrimitive]] 函数,对于该函数来说,算法逻辑一般来说如下:

  • 如果已经是原始类型了,就不需要转换了(因为可以重写Symbol.toPrimitive,所有这种情况是存在的)

  • 如果需要转换为字符串类型,则直接调用toString方法,转换为基础类型的话就返回转换的值。

  • 如果不是字符串类型,则先调用valueOf方法,结果不是基础类型的话再调用toString方法

  • 如果以上处理后,都没有返回原始类型,就会报错

本人小疑惑:有哪些对象调用valueof方法后会转换为基础类型? (发现一个,Date对象)

四则运算符

  • 加法

    • 运算中其中一方为字符串,那么就会把另一方也转换为字符串

    • 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串(具体转换参照对象转原始类型)

    1 + '1' // '11'
    true + true // 2
    4 + [1,2,3] // "41,2,3"
    
  • 其他运算符

    • 只要其中一方是数字,那么另一方就会被转为数字
    4 * '3' // 12
    4 * [] // 0
    4 * [1, 2] // NaN
    

比较运算符

1.如果是对象,则转换为原始类型再比较值

2.如果是字符串,就通过unicode字符索引来比较(我猜测是逐个字符进行对比大小,希望知道的朋友不吝赐教)

'6'.charCodeAt()  //54
'啊'.charCodeAt() //21834
'6' < '啊'        //true
'6' > '5啊'       //true

this

三种最常见的场景:

//1
function foo() {
  console.log(this.a)
}
var a = 1
foo()

//2
const obj = {
  a: 2,
  foo: foo
}
obj.foo()

//3
const c = new foo()
  • 对于直接调用foo来说,不管foo函数被放在了什么地方,this一定是window

  • 对于obj.foo()来说,我们只需要记住,谁调用了函数,谁就是this,所以在这个场景下foo函数中的this就是obj对象

  • 对于new的方式来说,this被永远绑定在了c上面,不会被任何方式改变this

箭头函数

function a() {
  return () => {
    return () => {
      console.log(this)
    }
  }
}
console.log(a()()())

首先箭头函数其实是没有this的,箭头函数中的this只取决包裹箭头函数的第一个普通函数的this。在这个例子中,因为包裹箭头函数的第一个普通函数是a,所以此时的thiswindow

bind

let a = {}
let fn = function () { console.log(this) }
fn.bind().bind(a)() // => ?

不管我们给函数bind几次,fn中的this永远由第一次bind决定,所以结果永远是window

// fn.bind().bind(a) 等于
let fn2 = function fn1() {
  return function() {
    return fn.apply()
  }.apply(a)
}
fn2()

优先级

多个规则同时出现时,这时候不同的规则之间会根据优先级最高的来决定this最终指向哪里。
首先,new的方式优先级最高,接下来是bind这些函数,然后是obj.foo()这种调用方式,最后是foo这种调用方式,同时,箭头函数的this一旦被绑定,就不会再被任何方式所改变。

原文地址:https://www.cnblogs.com/wangxi01/p/12753711.html