面试记录2(上一篇编辑不了)

53 阅读2分钟

手撕栈

class Stack{
    constructor(){
        this.arr = []
        this.topIdx = -1 //记录栈顶 
    }
    push(val){
        this.arr[++this.topIdx] = val
    }
    pop(){
        let tmp = this.top()
        this.topIdx --
        return tmp
    }
    top(){
        return this.arr[this.topIdx]
    }
    isEmpty(){
        return this.topIdx === 0
    }
}
let myStack = new Stack()
myStack.push(5)
myStack.push(7)

console.log(myStack.arr) //[ 5, 7 ]
console.log(myStack.pop()) //7
console.log(myStack.top()) 
//myStack.top is not a function 
//命名冲突 top ,当时属性和方法都定义了top
console.log(myStack.isEmpty()) //true

手撕instanceof

function instanceOf(obj,className){
    console.log("1",typeof className === 'function')
     //第一个参数是引用类型,第二个参数是函数
    if(typeof className !== 'function') throw new TypeError('The second argument must be a constructor function')
   
    if(obj === null || typeof obj != 'object') return false
    // prototype是函数的属性,__proto__是对象的属性
    // Object.getPrototypeOf()
    let proto = Object.getPrototypeOf(obj)
    while(proto){
        if(proto === className.prototype){
            return true
        }
        proto = Object.getPrototypeOf(proto)
    }
    return false
}

/*
//测试1
class Person {
    constructor(name){
        this.name = name;
    }
}
class student extends Person{
    constructor(name,age){
        super(name);
        this.age = age;
    }
}
const stu=new student("zhangsan",23)
console.log(instanceOf(stu,Person)); //true
console.log(stu instanceof Person) //true
console.log(stu instanceof student) //true
*/

/*
//测试2
let e = 888 , flag = true
console.log(instanceOf(e,Number)) //false
console.log(instanceOf(flag,Boolean)) //false
console.log(e instanceof Number) //false
*/

/*
//测试3
console.log(e instanceof null) //报错
console.log(instanceOf(e,null)) //报错
*/

a = new Number(888)
console.log(instanceOf(a , Number)) //true
console.log(instanceOf(888 , Number)) //false
b = new String('Egg')
console.log(instanceOf(b , String)) //true
c = new Array(6,66,666)
console.log(instanceOf(c , Array)) //true
d = new Object()
console.log(instanceOf(d , Object)) //true
  <script>
        // prototype 原型|原型对象
        // 是一个 【函数】 的属性
        // 是一个对象
        // 创建函数的时候默认会添加prototype这个属性
        /*
        function test(){}
        console.dir(test) //查看属性
        console.dir(test.prototype)  //Object
        */

        // __proto__ 隐式原型
        // 【对象】 的属性
        // 也是一个对象
        // 指向构造函数的prototype => obj.__proto__ === test.prototype true
        /*
        function test(name){
            this.name = name
        }
        const obj = new test('xiaoming')
        console.log(obj.__proto__ === test.prototype) //指向构造函数的prototype
        */

        // prototype是一个对象,也有__proto__属性
        // 这个__proto__属性 会指向构造函数的prototype
        // 下面这个例子的构造函数是Object
        // => test.prototype.__proto__ === Object.prototype true
        
        function test(name){
            this.name = name
        }
        console.log(test.prototype.__proto__ === Object.prototype)
        
        // prototype是一个对象 ,也有__proto__属性
        // console.log(Object.prototype.__proto__) //null
        // 已经是顶层了

        /* 目前形成的原型链
        obj {
            __proto__:test.prototype = {
                __proto__:Object.prototype = {
                    __proto__:null
                }
            }
        }
        */

        // 查找实例
        function test(){
            this.a = 1
        }
        test.prototype.b = 2
        const obj  = new test()
        Object.prototype.c = 3
        console.log(obj.a) //1
        console.log(obj.b) //2
        console.log(obj.c)
        /*
        此时的原型链
        obj {
            a : 1
            __proto__ : test.prototype = {
                b:2
                __proto__ : Object.prototype = {
                    c:3
                    __proto__:null
                }
            }
        }
            */
            
        //每个对象都有一个内部属性 `[[Prototype]]`,它指向该对象的原型
        //`__proto__` 是早期 JavaScript 引擎(如 Firefox)提供的一个属性,它允许开发者访问和设置一个对象的 `[[Prototype]]` 属性
        //ECMAScript 5 引入了 `Object.getPrototypeOf()` 方法,这是一个标准的方法来获取一个对象的 `[[Prototype]]` 属性
        //同样,ECMAScript 2015(ES6)引入了 `Object.setPrototypeOf()` 方法,用于设置一个对象的 `[[Prototype]]` 属性
        //因此,虽然在实践中 `__proto__` 属性和 `[[Prototype]]` 属性通常指向同一个对象,但它们并不完全相同。`[[Prototype]]` 是 ECMAScript 规范中定义的内部属性,而 `__proto__` 是一个便利属性,它在某些 JavaScript 引擎中提供了对 `[[Prototype]]` 属性的访问。
    </script>