手撕栈
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)
console.log(myStack.pop())
console.log(myStack.top())
console.log(myStack.isEmpty())
手撕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
let proto = Object.getPrototypeOf(obj)
while(proto){
if(proto === className.prototype){
return true
}
proto = Object.getPrototypeOf(proto)
}
return false
}
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>