越努力,越幸运,做个ccode~

0%

JS基础巩固篇

一些关于JS的基础知识巩固复习、整理

学了忘 忘了学。。。

一 instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

1
arr = [1,2,3]
2
arr instanceof Array  
3
// true  因为 arr.__proto__ === Array.prototype
4
arr instanceof Object  
5
// true  因为 arr.__proto__.__proto__ === Object.prototype

一般情况下instanceof 不能判断基本类型

1
'abc' instanceof String   // false
2
123 instanceof Number     // false
3
true instanceof Boolean   // false

自己实现 instanceof

1
const myInstanceof = function(instance, constructor){
2
  // 如果是基本类型就返回false 用 typeof 判断
3
  if(typeof instance !== 'object' && typeof instance !== 'function' || instance === null){
4
    return false
5
  }
6
7
  let proto = instance.__proto__   
8
  // 或者 proto = Object.getPrototypeOf(instance)
9
10
  while(proto !== null){   // 因为原型链的终点是 null
11
    if(proto === constructor.prototype) return true 
12
    proto = proto.__proto__
13
  }
14
  return false
15
16
  // 或者直接用isPrototypeOf判断
17
  // return constructor.prototype.isPrototypeOf(instance)
18
}

测试一下

1
myInstanceof(123,Object)         // false
2
myInstanceof('abc',String)       // false
3
myInstanceof([],Array)           // true
4
myInstanceof([],Object)          // true
5
myInstanceof({},Array)           // false
6
myInstanceof({},Object)          // true
7
myInstanceof(Math.max,Function)  // true

二 call bind apply的区别

这三个方法都是在函数的原型链上的方法,作用是用来改变this指向
这三个函数的第一个参数都是指定this

call方法

1
// 通过数组的方法将类数组转为数组avascript
2
let arr3 = {0:1,1:0,2:3,3:2,length:4}
3
Array.prototype.slice.call(arr3)  // 这样arr3本来没有slice方法 现在也可以使用了

apply方法

apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

appyl与call的区别

  • call的第二个参数传的是参数列表
  • apply的第二个参数传的的数组
1
// 求最大值
2
Math.max(1,3,4,2)  // 4
3
Math.max.call(null,1,3,2,4)
4
Math.max.apply(null,[1,3,2,4])  // 这样可以直接求数组中的最大值

bind方法

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
bind改变this指向后不会立即调用 而是返回一个yongq8

1
let obj = {
2
  say(){
3
    console.log(this)
4
  }
5
}
6
setTimeout(obj.say,1000)   // 调用的时候打印的this是window,1000)
7
// 我们可以通过bind绑定this
8
setTimeout(obj.say.bind(obj),2000)   // 打印的时候是obj
9
10
const fn = function(){
11
  console.log(this.name)
12
}
13
let obj = {
14
  name: 'obj 的name'
15
}
16
let objFn = fn.bind(obj)
17
objFn()  // 'obj'的name

三 Object.defineProperty

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

对象数据属性默认有四个特性

  • value 值 默认为undefined
  • configurable (是否可修改描述符对象 是否能通过delete删除属性 默认为false)
  • enumerable (是否可被遍历 默认为false)
  • writable (是否可改变 默认为false)

对象访问器属性 不包含数据值 有四个特性:

  • Configurable
  • Enumerable
  • Get
  • Set

要修改属性的默认特性,必须使用Object.defineProperty()方法 接受三个参数: 属性所在的对象 属性的名字 一个描述符对象

1
const object = {};
2
3
Object.defineProperty(object, 'property1', {
4
  value: 42,
5
  writable: false,      // 值不可变
6
  configurable: true,   // 可以被修改 可以被delete
7
  enumerable: false
8
})
9
10
object.property1 = 77   // throws an error in strict mode
11
console.log(object.property1)  // 42 因为该属性的值是不可改变的
12
13
Object.defineProperty(object, 'property1', {
14
  value: 42,
15
  writable: true,      // 重新修改为值可变
16
})
17
18
object.property1 = 77
19
console.log(object.property1)   // 77 现在值是可变的
20
21
delete object.property1   // true 可以被删除
22
23
Object.defineProperty(object,'property2',{
24
  value: 55,
25
  enumerable: true
26
})
27
28
// 可被遍历的属性
29
Object.keys(object)   // ['property2'] 因为property2的enumerable是true
30
for(let key in object) {
31
  console.log(key)       // 'property2'  只有一个属性可被遍历到
32
}
33
34
Object.property2 = 77  // throws an error in strict mode
35
console.log(Object.property2)  // 55 默认就是不可变的
36
37
Object.defineProperty(object,'property2',{
38
  writable: true
39
})   // 报错 因为 configurable 默认为false 不可再重新定义描述符对象
40
 
41
delete object.property2  // false configurable 默认为false 属性不可被删除

定义访问器属性

1
var book = {
2
   _year: 2004,
3
   edition: 1
4
}
5
6
Object.defineProperty(book,'year',{
7
  get: function(){
8
    return this._year
9
  },
10
  set: function(newValue){
11
    if(newValue){
12
      this._year = newValue
13
      this.edition += newValue - 2004
14
    }
15
  }
16
})
17
// {_year: 2004, edition: 1}
18
book.year = 2005  // 2005
19
book.edition      // 2

定义多个属性时可以用 Object.defineProperties方法

1
var obj = {};
2
Object.defineProperties(obj, {
3
  'property1': {
4
    value: true,
5
    writable: true
6
  },
7
  'property2': {
8
    value: 'Hello',
9
    writable: false
10
  }
11
  // etc. etc.
12
})

四 Object.getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor()方法可以读取属性的描述符

1
Object.getOwnPropertyDescriptor(object,'property1')

同理 Object.getOwnPropertyDescriptors()方法用来获取一个对象的所有自身属性的描述符