1043 字
5 分钟
JS基础巩固篇

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

学了忘 忘了学。。。

一 instanceof#

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

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

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

'abc' instanceof String // false
123 instanceof Number // false
true instanceof Boolean // false

自己实现 instanceof#

const myInstanceof = function(instance, constructor){
// 如果是基本类型就返回false 用 typeof 判断
if(typeof instance !== 'object' && typeof instance !== 'function' || instance === null){
return false
}
let proto = instance.__proto__
// 或者 proto = Object.getPrototypeOf(instance)
while(proto !== null){ // 因为原型链的终点是 null
if(proto === constructor.prototype) return true
proto = proto.__proto__
}
return false
// 或者直接用isPrototypeOf判断
// return constructor.prototype.isPrototypeOf(instance)
}

测试一下

myInstanceof(123,Object) // false
myInstanceof('abc',String) // false
myInstanceof([],Array) // true
myInstanceof([],Object) // true
myInstanceof({},Array) // false
myInstanceof({},Object) // true
myInstanceof(Math.max,Function) // true

二 call bind apply的区别#

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

call方法#

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

apply方法#

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

appyl与call的区别

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

bind方法#

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

let obj = {
say(){
console.log(this)
}
}
setTimeout(obj.say,1000) // 调用的时候打印的this是window,1000)
// 我们可以通过bind绑定this
setTimeout(obj.say.bind(obj),2000) // 打印的时候是obj
const fn = function(){
console.log(this.name)
}
let obj = {
name: 'obj 的name'
}
let objFn = fn.bind(obj)
objFn() // 'obj'的name

三 Object.defineProperty#

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

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

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

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

  • Configurable
  • Enumerable
  • Get
  • Set

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

const object = {};
Object.defineProperty(object, 'property1', {
value: 42,
writable: false, // 值不可变
configurable: true, // 可以被修改 可以被delete
enumerable: false
})
object.property1 = 77 // throws an error in strict mode
console.log(object.property1) // 42 因为该属性的值是不可改变的
Object.defineProperty(object, 'property1', {
value: 42,
writable: true, // 重新修改为值可变
})
object.property1 = 77
console.log(object.property1) // 77 现在值是可变的
delete object.property1 // true 可以被删除
Object.defineProperty(object,'property2',{
value: 55,
enumerable: true
})
// 可被遍历的属性
Object.keys(object) // ['property2'] 因为property2的enumerable是true
for(let key in object) {
console.log(key) // 'property2' 只有一个属性可被遍历到
}
Object.property2 = 77 // throws an error in strict mode
console.log(Object.property2) // 55 默认就是不可变的
Object.defineProperty(object,'property2',{
writable: true
}) // 报错 因为 configurable 默认为false 不可再重新定义描述符对象
delete object.property2 // false configurable 默认为false 属性不可被删除

定义访问器属性

var book = {
_year: 2004,
edition: 1
}
Object.defineProperty(book,'year',{
get: function(){
return this._year
},
set: function(newValue){
if(newValue){
this._year = newValue
this.edition += newValue - 2004
}
}
})
// {_year: 2004, edition: 1}
book.year = 2005 // 2005
book.edition // 2

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

var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// etc. etc.
})

四 Object.getOwnPropertyDescriptor#

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

Object.getOwnPropertyDescriptor(object,'property1')

getOwnPropertyDescriptor

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

JS基础巩固篇
https://blog.cxyxiaoyu.top/posts/js基础巩固篇/
作者
小宇
发布于
2020-08-30
许可协议
CC BY-NC-SA 4.0