js 常见的原理面试题总结(二)

本文探讨了JavaScript中实现继承的技巧,通过借用构造函数继承实例属性,并详细解析了EventBus的基本实现,包括事件的存储、定义及触发过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1: js实现一个继承方法// 借用构造函数继承实例属性

// js实现一个继承方法,借用构造函数继承实例属性
function Person(){
    this.name="xiaomi";
    this.age=21;
}
Person.prototype.eat=function(){console.log("food");}    

function Coder(){
    this.weight=120;
    this.height=170;
    Person.call(this)  // 拿到父类的数据
}
Coder.prototype= new Person();  // 继承父类的方法,此时也拿到父类的属性
Coder.prototype.constructor=Coder;  // 改变原型对象下的constructor指针的指向

var me= new Coder();
console.log(me);            //Coder { weight: 120, height: 170, name: 'xiaomi', age: 21 }
console.log(me.__proto__);  //Coder { name: 'xiaomi', age: 21, constructor: [Function: Coder] }
me.eat();                   //food

2: 实现一个基本的Event Bus

(1): 前置知识,了解 new Map() 对象的属性和方法


// ES6中的 new Map() 对象的使用
// clear: 从映射中移除所有的元素
// delete: 从映射中移除指定的元素
// forEach: 对映射中的每个元素执行指定操作
// get: 返回映射中的制定元素
// has: 如果映射包含指定元素则返回true
// set: 添加一个新建元素到映射
// toString: 返回映射的字符串形式
// valueOf:  返回制定对象的原始值

var myMap= new Map();
console.log(myMap);
// size 可以返回映射中的元素数
myMap.set(1,"one");
myMap.set("2", "two");
myMap.set(true,"yes");
myMap.set("函数",function(){console.log("test")})
myMap.set(undefined, "未定义");
myMap.set({name: "xiaoming"},"对象");
myMap.set(Symbol(), "symbol对象");

myMap.set(1,"one2");
myMap.set(1,"one3");  
console.log(myMap.get("函数")); 
myMap.clear();   // 清空 map
myMap.delete(1);   // 删除: key 为1的元素
myMap.forEach((item,key,mapObj)=>{
    console.log(item,key);
});

console.log(myMap.get(1));
console.log(myMap.get({name: "xiaoming"})); // undefined ,两个对象不是一个
console.log(myMap.get(true));
console.log(myMap.has("2"));  // true , 是否包含指定元素

实现EventEmitter原理代码:

// 实现一个基本的Event Bus
// 定义一个对象; 存储事件, 定义事件, 触发事件
// 事件: (事件类型,事件处理函数)
class EventEmitter {
    constructor() {
        this.events = new Map();// 用于存储事件

        // 添加事件类型以及其事件处理函数
        this.addListener=function(type, callback){
            // 对于这个事件类型没有其对应的事件处理函数
            // 所以说对于一个事件类型只存在一个事件处理函数
            if(!this.events.get(type)){
                this.events.set(type,callback);
            }
        }

        // 触发事件
        this.emit=function(type){
            let handel=this.events.get(type);
            handel.call(this,...[...arguments].slice(1))
        }
    }
}

var eventEmitter= new EventEmitter();

eventEmitter.addListener("click", function(a,b){
    console.log("啊,被点击啦");
    console.log(a,b);
})

eventEmitter.emit("click",12,45);

3: 实现一个双向数据绑定

(1): 前置知识(代码中的注释是根据整体代码的语义进行注释的)

// configurable特性表示对象的属性是否可以被删除,
// 以及除value和writable特性外的其他特性是否可以被修改。
var obj={}
Object.defineProperty(obj, "name",{
    value: "xiaowang",
    writable: true,    // 如果不进行配置,对象的属性值不可以修改
    enumerable: true,   // 使对象的属性是可以枚举的
    // configurable: true
});

delete obj.name;    // 由于configurable 默认为false,不可以配置,所以不能删除
console.log(obj);    //    { name: 'xiaowang' }
console.log(obj.name);   // xiaowang


// 当试图改变不可配置属性(除了value和writable 属性之外)
// 的值时会抛出TypeError,除非当前值和新值相同。
Object.defineProperty(obj,"name",{
    value: "xiaowangfwv",
    writable: true,
    enumerable: true,  // 改为false的话会报错:Cannot redefine property: name
});


// 注意如果是在字面对象上面定义的属性:
// 其配置属性: writable, configurable, enumerable,
// 等配置属性的默认值都是:true 
var obj={
    name: "xiaowang",
    age:21
}
Object.defineProperty(obj,"name",{
    value: "xiaolan"
})
console.log(obj);

原理代码:

前台数据input 输入框value值发生改变时,后台接收到数据(并监听数据发生改变),

进而去向前台进行渲染新的数据,实现了双向数据绑定(前台->后台, 后台->前台)

let obj = {}
let input = document.getElementById('input')
let span = document.getElementById('span')
// 数据劫持
Object.defineProperty(obj, 'text', {
  configurable: true,
  enumerable: true,
  get() {
    console.log('获取数据了')
  },
  set(newVal) {
    console.log('数据更新了')
    input.value = newVal
    span.innerHTML = newVal
  }
})
// 输入监听
input.addEventListener('keyup', function(e) {
  obj.text = e.target.value
})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值