Skip to content

Latest commit

 

History

History
219 lines (196 loc) · 8.38 KB

基础概念.md

File metadata and controls

219 lines (196 loc) · 8.38 KB

基本概念

7 种数据类型: Null、Undefined、Number、Boolean、String、Object、Symbol

排除 Symbol 的话,高程中将 Undefined、Null、Number、Boolean、String 定义为基本数据类型,因为其是按值访问的,可以操作保存在变量中的实际的值。引用类型值 是保存在内存中的对象,操作对象时,实际上操作的是对象的引用。

js 中的值类型和引用类型的区别

如何判断变量的数据类型?使用typeof运算符:

  • typeof 对于基本类型,除了 null 都可以显示正确的类型
  • typeof 对于对象,除了函数都会显示 object
  • 对于 null 来说,虽然它是基本类型,但是会显示 object,这是一个存在很久了的 Bug
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof b // b没有声明,但是还会显示undefined

typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'
typeof null // 'object'

使用Object.prototype.toString.call(),该方法返回类似[object Type]形式的字符串

let a = []
let b = {}
let c = true
let d = 'string'
let e = null
let f = undefined
let g = 1
let h = function () {}
let i = Symbol('symbol')
console.log(Object.prototype.toString.call(a)) // [object Array]
console.log(Object.prototype.toString.call(b)) // [object Object]
console.log(Object.prototype.toString.call(c)) // [object Boolean]
console.log(Object.prototype.toString.call(d)) // [object String]
console.log(Object.prototype.toString.call(e)) // [object Null]
console.log(Object.prototype.toString.call(f)) // [object Undefined]
console.log(Object.prototype.toString.call(g)) // [object Number]
console.log(Object.prototype.toString.call(h)) // [object Function]
console.log(Object.prototype.toString.call(i)) // [object Symbol]
console.log('[object Array]' === Object.prototype.toString.call(a)) // true

if 条件判断时的注意事项

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 "" (空字符串)
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined n/a(不适用) undefined

逻辑非

  • 如果操作数是一个对象,返回 false
  • 如果操作数是一个空字符串,返回 true
  • 如果操作数是一个非空字符串,返回 false
  • 如果操作数是数值0,返回 true
  • 如果操作数是任意非0的值(包括 Infinity),返回 false
  • 如果操作数是 null,返回 true
  • 如果操作数是 NaN,返回 true
  • 如果操作数是 undefined,返回 true

四则运算注意事项

只有当加法运算时,其中一方是字符串类型,就会把另一个也转为字符串类型。其他运算只要其中一方是数字,那么另一方就转为数字。并且加法运算会触发三种类型转换:将值转换为原始值,转换为数字,转换为字符串。

1 + '1' // '11'
2 * '2' // 4
[1, 2] + [2, 1] // '1,22,1'
// [1, 2].toString() -> '1,2'
// [2, 1].toString() -> '2,1'
// '1,2' + '2,1' = '1,22,1'

对于加号需要注意这个表达式'a' + + 'b'

'a' + + 'b' // -> "aNaN"
// 因为 + 'b' -> NaN
// 你也许在一些代码中看到过 + '1' -> 1

toString() 方法的使用

数值、布尔值、对象和字符串值(没错,每个字符串也都有一个 toString() 方法,该方法返回字符串的一个副本)都有 toString() 方法。但 null 和 undefined 值没有这个方法。

多数情况下,调用 toString() 方法不必传递参数。但是,在调用数值的 toString() 方法时,可以传递一个参数:输出数值的基数。默认情况下,toString() 方法以十进制格式返回数值的字符串表示。而通过传递基数,toString() 可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格式表示的字符串值。下面给出几个例子:

var num = 10
alert(num.toString()) // "10"
alert(num.toString(2))  // "1010"
alert(num.toString(8))  // "12"
alert(num.toString(10))  // "10"
alert(num.toString(16))  // "a"

变量、函数提升

在生成执行上下文时,会有两个阶段。第一个阶段是创建的阶段,JS 解释器会找出需要提升的变量和函数,并且给他们提前在内存中开辟好空间,函数的话会将整个函数存入内存中,变量只声明并且赋值为 undefined。在第二个阶段,也就是代码执行阶段,我们可以直接提前使用。在提升的过程中,同名的函数会覆盖上一个函数,并且函数优先于变量提升

简而言之:由于变量提升,使用 var 声明的变量声明前使用则值为 undefined(本作用域下),函数可以在声明之前就使用。

b() // call b
console.log(a) // undefined
var a = 'Hello world'
function b() {
  console.log('call b')
}
var b = 'I am a var'

instanceof

instanceof 运算符用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。 用法:对象 instanceof 构造函数

function Car(make, model, year) {
  this.make = make
  this.model = model
  this.year = year
}
var auto = new Car('Honda', 'Accord', 1998)

console.log(auto instanceof Car)
// expected output: true

console.log(auto instanceof Object)
// expected output: true

Object 对象

参考:https://www.jb51.net/article/80177.htm 对象实例的一些方法

  • hasOwnProperty(propertyName):接收一个字符串参数,该参数表示属性名称,用来判断该属性是否在当前对象实例中,而不是在对象的原型链中。
var arr = []
console.log(arr.hasOwnProperty("length")) // true
console.log(arr.hasOwnProperty("hasOwnProperty")) // false
// length 是 arr 自己的属性,而 hasOwnProperty 是原型链上的属性(方法)
  • isPrototypeOf(Object):isPrototype方法接收一个对象,用来判断当前对象是否在传入的参数对象的原型链上。关于原型链可参考原型与继承章节。
function MyObject() {}
var obj = new MyObject()
console.log(Object.prototype.isPrototypeOf(obj)) // true
  • toString():返对象的字符串表示
  • valueOf():返回对象的原始值,可能是字符串、数值、bool 值等,看具体的对象

特性操作的相关方法:

  • Object.defineProperty(obj, propName, descriptor):接收三个参数,obj 是需要定义属性的对象,propName 是需要被定义的属性名,descriptor 是属性描述符,包含一些属性的特性定义
var obj = {}
Object.defineProperty(obj, "name", {
  value: "name",
  configurable: true,
  writable: true,
  enumerable: true
})
  • Object.defineProperties():与 defineProperty 不同之处在于可以同时定义多个属性
var obj = {};
Object.defineProperty(obj, {
  "name": {
    value: "name",
    configurable: true,
    writable: true,
    enumerable: true
  },
  "age": {
    value: 20 
  }
})
  • Object.getOwnPropertyDescriptor(obj, propName):用于读取特性值,接收对象及其属性名两个参数,返回一个对象
var person = {
  _age: 10,
  type: "小孩"
}
Object.defineProperty(person, "age", {
  get: function () {
    return this._age
  },
  set: function (newValue) {
    this._age = newValue
    this.type = newValue > 17 ? "成人" : "小孩"
  }
})
 
console.log(Object.getOwnPropertyDescriptor(person, "type")) 
// Object {value: "成人", writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(person, "age")) 
// Object {enumerable: false, configurable: false, get: function(),set: function ()}

其他:

  • Object.getOwnPropertyNames():用于获取对象自身的所有属性,包括可枚举和不可枚举的所有属性,返回一个数组
function Parent() {
  this.lastName = "Black"
}
function Child(firstName) {
  this.firstName = firstName
}
Child.prototype = new Parent()
 
var son = new Child("Jack");
Object.defineProperty(son, "age", {
  enumerable: false
})
console.log(Object.keys(son)) // ["firstName"] 
console.log(Object.getOwnPropertyNames(son)) // ["firstName", "age"]
  • Object.keys():用于获取给定对象的所有可枚举的自身属性的属性名,它返回一个数组,例子如上