核心概念✅
下面代码中 a 在什么情况下会打印 1 ?
const a = {
// 实现 a 对象
}
// 使得此处等式成立
if (a == 1 && a == 2 && a == 3) {
console.log(1)
}
答案
const a = {
i: 1,
toString: function () {
return this.i++
}
}
// eslint-disable-next-line
if (a == 1 && a == 2 && a == 3) {
console.log(1)
}
在这个例子中,a
被定义为一个对象,有一个属性 i
初始化为 1,同时重写了 toString
方法,在每次调用时返回 i
的值,并且每次返回后将 i
自增。这样在比较 a
是否等于 1、2、3 的时候,会依次调用 a.toString()
方法,得到的结果就是满足条件的 1,依次打印出来。
深拷贝和浅拷贝
实现一个 sum 函数,支持任意个参数的累加,在 console.log 时输出结果?
// example1
console.log(sum(1)(2)(3, 4)) // 10
// example2
console.log(sum(1, 2, 3, 4)) // 10
答案
function sum (...args) {
let total = args.reduce((a, b) => a + b, 0)
function inner (...rest) {
total += rest.reduce((a, b) => a + b, 0)
return inner
}
inner.toString = inner.valueOf = () => total
inner[Symbol.toPrimitive] = () => total
return inner
}
// example1
console.log(+sum(1)(2)(3, 4)) // 10
// example2
console.log(+sum(1, 2, 3, 4)) // 10
模拟new操作
答案
在 JavaScript 中,new
关键字的核心作用是:
- 创建一个新的空对象;
- 将新对象的原型指向构造函数的
prototype
; - 将构造函数内部的
this
绑定到新对象; - 执行构造函数逻辑;
- 如果构造函数返回一个对象,则返回该对象,否则返回新创建的对象。
自定义实现时需注意:
- 必须正确设置原型链;
- 需处理构造函数显式返回对象的情况;
- 不能省略
this
绑定和参数传递。
实现代码如下:
function myNew (constructor, ...args) {
// 1. 创建一个新对象,原型指向构造函数的 prototype
const obj = Object.create(constructor.prototype)
// 2. 执行构造函数,将 this 绑定到新对象
const result = constructor.apply(obj, args)
// 3. 返回构造函数返回的对象(如果是对象),否则返回新对象
return (typeof result === 'object' && result !== null) ? result : obj
}
使用示例:
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function () {
console.log(`Hi, I'm ${this.name}, ${this.age} years old.`)
}
const p = myNew(Person, 'Alice', 20)
p.sayHi() // Hi, I'm Alice, 20 years old.
实现链式调用 ?
答案
链式调用是指多个方法可以连续调用,每个方法返回当前对象,以便可以继续调用其他方法。实现链式调用通常需要在每个方法中返回 this
,以保持对当前对象的引用。
class Chainable {
constructor (value) {
this.value = value
}
add (num) {
this.value += num
return this
}
subtract (num) {
this.value -= num
return this
}
multiply (num) {
this.value *= num
return this
}
divide (num) {
this.value /= num
return this
}
getValue () {
return this.value
}
}
const result = new Chainable(10)
.add(5)
.subtract(2)
.multiply(3)
.divide(2)
.getValue()
console.log(result) // 19.5