javascript"> functionFoo(){getName=function(){console.log(1)}returnthis}Foo.getName=function(){console.log(2)}Foo.prototype.getName=function(){console.log(3)}// 在变量提升之后,此时5的函数会被4给替换,因为前面的getName在变量提升之后是5函数vargetName=function(){console.log(4)}functiongetName(){console.log(5)}// 请写出以下的输出结果Foo.getName()// 2getName()//4// 这里的执行顺序是先执行Foo函数,也就是(Foo()).getName(),// Foo执行后,函数中的getName没有变量修饰符,也就是会在全局变量中找,那么此时全局变量中的getName被1函数赋值了// Foo返回了一个this值,this指向window,最后的变成window.getName(),此时getName是全局函数,因此会执行,输出1Foo().getName()//1// 此时getName已经被修改了getName()//1// new (Foo.getName)() ==> new (function(){console.log(2);})() 会执行该函数并产生一个实例对象newFoo.getName()//2 // new Foo()是一个实例对象,此时类的原型对象上有一个getName函数,输出newFoo().getName()//3// new ((new Foo()).getName)() ==> new (function(){console.log(3);})() 执行该函数newnewFoo().getName()//3
javascript"> functionNew(fn,...args){// 创建一个空的对象并链接到构造函数的原型,使它能访问原型中的属性const instance = object.create(fn.prototype)// 使用apply改变构造函数中this的指向实现继承,使obj能访问到构造函数中的属性const res =fn.apply(instance, args)// 优先返回构造函数返回的对象returntypeof res ==='object'||typeof res ==='function'? res : instance}functionPerson(name){this.name = name}Person.prototype.eat=function(){console.log('Eatting')}var lindaidai =New(Person,'LinDaiDai')console.log(lindaidai,'New')// Person{ name: 'LinDaiDai' }lindaidai.eat()// 'Eatting'
手写call、apply、bind
javascript"> Function.prototype.Call=function(context,...args){if(!context) context = windowconst f =Symbol()context[f]=thisconst res = context[f](...args)delete context[f]return res}Function.prototype.Apply=function(context,...args){if(!context) context = windowconst f =Symbol()context[f]=thisconst res = context[f](args)delete context[f]return res}Function.prototype.Bind=function(context,...args){if(!context) context = windowconst f =Symbol()context[f]=thisreturnfunction(...args1){const res = context[f](...args,...agrs1)delete context[f]return res}}var obj ={name:'objName',}var name ='globalName'functionconsoleInfo(sex, weight){console.log(this.name, sex, weight,'this指向 call apply bind')}consoleInfo('man',100)// 'globalName' 'man' 100consoleInfo.Call(obj,'man',100)// 'objName' 'man' 100consoleInfo.Call(obj,'woman',120)// 'objName' 'woman' 120consoleInfo.Apply(obj,['man',100])// 'objName' 'man' 100consoleInfo.Apply(obj,['woman',120])// 'objName' 'woman' 120consoleInfo.Bind(obj,'man',100)()// 'objName' 'man' 100consoleInfo.Bind(obj,'woman',120)()// 'objName' 'woman' 120
相关题目
javascript"> var a =10functionfoo(){// 默认模式下 函数的this执行windowconsole.log(this.a)// 10}foo()
javascript"> 'use strict'var a =10functionfoo(){// 严格模式下 函数的this 指向 undefinedconsole.log('this1',this)// undefinedconsole.log(window.a)// 10console.log(this.a)// 报错,undefined上没a}console.log(window.foo)// f foo(){...}console.log('this2',this)// windiowfoo()
javascript"> // let const 声明的变量不存在变量提升 window下无 a,b 变量let a =10const b =20functionfoo(){console.log(this.a)// undefinedconsole.log(this.b)// undefined}foo()console.log(window.a)// undefined
javascript"> // let const 声明的变量不存在变量提升 window下无 a,b 变量let a =10const b =20functionfoo(){console.log(this.a)// undefinedconsole.log(this.b)// undefined}foo()console.log(window.a)// undefined
javascript"> var a =1functionfoo(){var a =2console.log(this)// windowconsole.log(this.a)// 1}foo()
javascript"> var a =1functionfoo(){var a =2functioninner(){// 默认模式下,函数的this指向widowconsole.log(this.a)// 1}inner()}foo()
javascript"> functionfoo(){console.log(this.a)returnfunction(){console.log(this.a)}}var obj ={ a:1}var a =2foo()// 2foo.bind(obj)foo().bind(obj)// 2
javascript"> functionfoo(){console.log(this.a)returnfunction(){console.log(this.a)}}var obj ={ a:1}var a =2foo.call(obj)()// 1 2
javascript"> var obj ={a:'obj',foo:function(){console.log('foo:',this.a)returnfunction(){console.log('inner:',this.a)}},}var a ='window'var obj2 ={ a:'obj2'}obj.foo()()// 'foo:obj' 'inner:window'obj.foo.call(obj2)()// 'foo:obj2' 'inner:window'obj.foo().call(obj2)// foo:'obj' 'inner:obj2'
javascript"> var obj ={a:1,foo:function(b){b = b ||this.areturnfunction(c){console.log(this.a + b + c)}},}var a =2var obj2 ={ a:3}obj.foo(a).call(obj2,1)// 6 a = 3 b = 2 c = 1obj.foo.call(obj2)(1)// 6 a = 2 b = 3 c = 1
javascript"> functionfoo1(){console.log(this.a)}var a =1var obj ={a:2,}varfoo2=function(){foo1.call(obj)}foo2()// 2foo2.call(window)// 2
javascript"> functionfoo1(b){console.log(`${this.a} + ${b}`)returnthis.a + b}var a =1var obj ={a:2,}varfoo2=function(){returnfoo1.call(obj,...arguments)}var num =foo2(3)// 2 + 3console.log(num)// 5
javascript"> var name ='window'functionPerson(name){this.name = namethis.foo=function(){console.log(this.name)returnfunction(){console.log(this.name)}}}var person1 =newPerson('person1')var person2 =newPerson('person2')person1.foo.call(person2)()// 'person2' windowperson1.foo().call(person2)// 'person1' 'person2'
javascript"> var obj ={name:'obj',foo1:()=>{console.log(this.name)},foo2:function(){console.log(this.name)return()=>{console.log(this.name)}},}var name ='window'obj.foo1()// windowobj.foo2()()// obj obj
javascript"> var name ='window'var obj1 ={name:'obj1',foo:function(){console.log(this.name)},}var obj2 ={name:'obj2',foo:()=>{console.log(this.name)},}obj1.foo()// obj1obj2.foo()// window
javascript"> var name ='window'var obj1 ={name:'obj1',foo:function(){console.log(this.name)returnfunction(){console.log(this.name)}},}var obj2 ={name:'obj2',foo:function(){console.log(this.name)return()=>{console.log(this.name)}},}var obj3 ={name:'obj3',foo:()=>{console.log(this.name)returnfunction(){console.log(this.name)}},}var obj4 ={name:'obj4',foo:()=>{console.log(this.name)return()=>{console.log(this.name)}},}obj1.foo()()// obj1 windowobj2.foo()()// obj2 obj2obj3.foo()()// window windowobj4.foo()()// window window
javascript"> var name ='window'functionPerson(name){this.name = namethis.foo1=function(){console.log(this.name)}this.foo2=()=>{console.log(this.name)}}var person2 ={name:'person2',foo2:()=>{console.log(this.name)},}var person1 =newPerson('person1')person1.foo1()// person1person1.foo2()// person1person2.foo2()// window
javascript"> var name ='window'functionPerson(name){this.name = namethis.foo1=function(){console.log(this.name)returnfunction(){console.log(this.name)}}this.foo2=function(){console.log(this.name)return()=>{console.log(this.name)}}this.foo3=()=>{console.log(this.name)returnfunction(){console.log(this.name)}}this.foo4=()=>{console.log(this.name)return()=>{console.log(this.name)}}}var person1 =newPerson('person1')person1.foo1()()// person1 windowperson1.foo2()()// person1 person1person1.foo3()()// person1 windowperson1.foo4()()// person1 person1
javascript"> var name ='window'var obj1 ={name:'obj1',foo1:function(){console.log(this.name)return()=>{console.log(this.name)}},foo2:()=>{console.log(this.name)returnfunction(){console.log(this.name)}},}var obj2 ={name:'obj2',}obj1.foo1.call(obj2)()// obj2 obj2obj1.foo1().call(obj2)// obj1 obj1obj1.foo2.call(obj2)()// window windowobj1.foo2().call(obj2)// window obj2
javascript"> var name ='window'var person1 ={name:'person1',foo1:function(){console.log(this.name)},foo2:()=> console.log(this.name),foo3:function(){returnfunction(){console.log(this.name)}},foo4:function(){return()=>{console.log(this.name)}},}var person2 ={ name:'person2'}person1.foo1()// person1person1.foo1.call(person2)// preson2person1.foo2()// windowperson1.foo2.call(person2)// windowperson1.foo3()()// windowperson1.foo3.call(person2)()// windowperson1.foo3().call(person2)// person2person1.foo4()()// person1person1.foo4.call(person2)()// person2person1.foo4().call(person2)// person1
1) Class 类可以看作是构造函数的语法糖
2) Class 类中定义的方法,都是定义在该构造函数的原型上
3)使用static关键字,作为静态方法(静态方法,只能通过类调用,实例不能调用)
4)extents 关键字实际是寄生组合继承了避免与访问器属性冲突,在构造函数中使用了一个带有下划线前缀的私有属性_myProperty。这是一种常见的命名约定,用于表示该属性应该被视为私有的,以防止直接访问
javascript">functionFoo(){getName=function(){console.log(1)}returnthis}// 静态方法Foo.getName=function(){console.log(2)}// 成员方法Foo.prototype.getName=function(){console.log(3)}// 函数提升优先级高于变量提升,且不会被同名变量声明时覆盖,但是会被同名变量赋值后覆盖vargetName=function(){console.log(4)}functiongetName(){console.log(5)}//请写出以下输出结果:Foo.getName()// 2getName()// 4// Foo().getName(); // undefined is not a functiongetName()// 4newFoo.getName()// 2newFoo().getName()// 3newnewFoo().getName()// 3
Promise
手写promise
javascript"> classMyPromise{constructor(execute){this.state ='pending'this.data =undefinedthis.error =undefinedthis.resolveTask =[]this.rejectTask =[]try{execute(this.resolve.bind(this),this.reject.bind(this))}catch(e){this.reject(e)}}resolve=(value)=>{if(this.state !=='pending')returnthis.state ='fulfilled'this.data = valuethis.resolveTask.forEach(cb=>cb())}reject=(error)=>{if(this.state !=='pending')returnthis.state ='rejected'this.error= errorthis.rejectTask .forEach(cb=>cb())}then=(onResolve, onReject)=>{onResolve =typeof onResolve ==='function'?onResolve:value=> valueonReject =typeof onReject ==='function'?onReject:(error)=>throw errorreturnnewMyPromise((resolve, reject)=>{this.resolveTask.push(()=>{const res =onResolve(this.data)if(res instanceofMyPromise){res.then(resolve, reject)}else{resolve(res)}})this.rejectTask.push(()=>{const res =onReject(this.error)if(res instanceofMyPromise){res.then(resolve, reject)}else{reject(res)}})})}catch=(onReject)=>{returnthis.then(undefined, onReject)}staticresolve=(value)=>{returnnewMyPromise((resolve, reject)=>{if(value instanceofMyPromise){value.then(resolve, reject)}else{resolve(value)}})}staticreject=(error)=>{returnnewMyPromise((resolve, reject)=>{if(value instanceofMyPromise){error.then(resolve, reject)}else{reject(error)}})}staticrace=(promises)=>{returnnewMyPromise((resolve, reject)=>{for(let i =0; i < promises.length; i++){MyPromise.resolve(promises[i]).then(value=>{resolve(value)},error=>{reject(error)})}})}staticall=(promises)=>{const result =[]let index =0returnnewMyPromise((resolve, reject)=>{for(let i =0; i < promises.length; i++){MyPromise.resolve(promises[i]).then(value=>{result[i]= valueindex++if(index === promises.length -1){resolve(resolve(value))}},error=>{reject(error)})}})}staticretry(fn, delay, times){returnnewMyPromise((resolve, reject)=>{functionfunc(){MyPromise.resolve(fn()).then((res)=>{resolve(res)}).catch((err)=>{// 接口失败后,判断剩余次数不为0时,继续重发if(times !==0){setTimeout(func, delay)times--}else{reject(err)}})}func()})}}// 打印结果:依次打印1、2newMyPromise((resolve, reject)=>{setTimeout(()=>{resolve(1)},500)}).then((res)=>{console.log(res)returnnewMyPromise((resolve)=>{setTimeout(()=>{resolve(2)},1000)})}).then((data)=>{console.log(data)})
渲染的基本流程:1、处理 HTML 标记并构建 DOM 树。2、处理 CSS 标记并构建 CSSOM 树, 将 DOM 与 CSSOM 合并成一个渲染树。3、根据渲染树来布局,以计算每个节点的几何信息。4、将各个节点绘制到屏幕上。可以看到渲染树的一个重要组成部分是CSSOM树,绘制会等待css样式全部加载完成才进行,所以css样式加载的快慢是首屏呈现快慢的关键点。
for…of 遍历获取的是对象的键值,for…in 获取的是对象的键名;for… in 会遍历对象的整个原型链,性能非常差不推荐使用,而 for … of 只遍历当前对象不会遍历原型链;对于数组的遍历,for…in 会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for…of 只返回数组的下标对应的属性值;
手写Reduce
javascript"> Array.prototype.Reduce=function(fn, initValue){if(typeof fn !=='function'){thrownewTypeError(`${fn} is not a function`)}let pre, indexconst arr =this.slice()// 如果没有提供initValue,找到数组中的第一个存在的值作为pre,下一个元素的下标作为indexif(initValue ===undefined){for(let i =0; i < arr.length; i++){if(!arr.hasOwnProperty(i))continuepre = arr[i]index = i +1break}}else{// 如果提供了initValue时,则作为pre的初始值,index从0开始pre = initValueindex =0}for(let i = index; i < arr.length; i++){if(arr.hasOwnProperty(i)){// 函数接收4个参数 pre, cur, index, arraypre =fn.call(undefined, pre, arr[i], i,this)}}return pre}console.log([,,,1,2,3,4].Reduce((pre, cur)=> pre + cur))// 10
手写Map
javascript"> Array.prototype.Map=function(fn, context){if(typeof fn !=='function'){thrownewTypeError(`${fn} is not a function`)}const arr =this.slice()const list =newArray(arr.length)for(let i =0; i < arr.length; i++){if(arr.hasOwnProperty(i)){list[i]=fn.call(context, arr[i], i,this)}}return list}console.log([1,2,3].Map((item)=> item *2))// [2, 4, 6]
手写filter
javascript"> Array.prototype.Filter=function(fn, context){if(typeof fn !=='function'){thrownewTypeError(`${fn} is not a function`)}const list =[]for(let i =0; i <this.length; i++){if(fn.call(context,this[i], i,this)){list.push(this[i])}}return list}console.log([1,2,3,4].Filter((item)=> item >2))// [3, 4]
手写some
javascript"> Array.prototype.Some=function(fn){if(typeof fn !=='function'){thrownewTypeError(`${fn} is not a function`)}let result =falsefor(let i =0; i <this.length; i++){if(fn(this[i], i)){result =truebreak}}return result}console.log([1,2,3,4].Some((item)=> item >6))// falseconsole.log([1,2,3,4].Some((item)=> item >2))// true
手写Every
javascript"> Array.prototype.Every=function(fn){if(typeof fn !=='function'){thrownewTypeError(`${fn} is not a function`)}let result =falselet index =0for(let i =0; i <this.length; i++){if(fn(this[i], i)){index++if(index ===this.length -1){reslut =true}}}return result}console.log([1,2,3,4].Every((item)=> item >4))// falseconsole.log([1,2,3,4].Every((item)=> item >0))// true
Undefined Null Number String Boolean Object Symbol BigInt (后面两个ES6新增)
基础数据类型(存放在栈中):Undefined Null Number String Boolean Symbol BigInt
引用数据类型(存放在堆中):Object (对象、数组、函数)
isNaN 和 Number.isNaN
NaN 是一个特殊的警戒值,它表示非数字,并且它不等于自身 NaN !== NaN (true)typeof NaN === 'number' (true)isNaN 会将传入的值进行数字转换,任何不能进行数字转换的值都返回trueNumber.isNaN 会判断传入的值是否是数字,判断为数字再判断是不是NaN,不进行数据转换
undefined -> NaN null -> 0 true -> 1 false -> 0
'' -> 0 含有非数字的字符串 -> NaN
Symbol 不能转数字
转换到boolean
undfeined null +0 -0 '' NaN false 都为false 其余的逻辑上都为true
类型转换
javascript">// 当a等于什么的时候能使下面的条件成立var a =?if(a ==1&& a ==2&& a ==3){console.log(1);}/*** == 的转换规则* * 对象==字符串 对象.toStringnull==undefined 相等 但是和其他值不相等NaN!=NaN剩下的都转换成数字*/// 对象==字符串 对象.toString// 利用这个思想,将a写为一个对象,并且重写其toSrting方法,在第一次执行的时候返回1// 在第二次执行的时候返回2,第三次执行的时候返回3,使条件成立var a ={i:1,toString(){if(i =1){returnthis.i++}elseif(i =2){returnthis.i++}else{returnthis.i}}}// 利用Object.defineProperty进行数据劫持var i =0
Object.defineProperty(window,'a',{get(){return++i}})// 数组弹出var a =[1,2,3]
a.toString = a.shiftif(a ==1&& a ==2&& a ==3){console.log('成立')}
手写Typeof
javascript"> functionTypeof(context){returnObject.prototype.toString.call(context).slice(8,-1).toLowerCase()}constfoo=()=>{}const str ='1'const boo =falseconst n =nullconst u =undefinedconst s =Symbol()const b =BigInt(9007199254740991)console.log(Typeof(foo))console.log(Typeof(str))console.log(Typeof(boo))console.log(Typeof(n))console.log(Typeof(u))console.log(Typeof(s))console.log(Typeof(b))
手写instanceof
javascript"> functionInstanceof(context, fn){const proto = context.__proto__if(proto){if(proto === fn.prototype){returntrue}else{returnInstanceof(proto, fn)}}else{returnfalse}}constfoo=()=>{}const o =newObject()const a =newArray()const m =newMap()const w =newWeakMap()const s =newSet()console.log(Instanceof(foo, Function))console.log(Instanceof(o, Object))console.log(Instanceof(a, Array))console.log(Instanceof(m, Map))console.log(Instanceof(w, WeakMap))console.log(Instanceof(s, Set))
Pushgateway属于整个架构图的这一部分 The Pushgateway is an intermediary service which allows you to push metrics from jobs which cannot be scraped. The Prometheus Pushgateway exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. S…
1.下面哪种攻击属于被动攻击(D)。 A. 拒绝服务 B.端口扫描 C. 缓冲区溢出 D. 网络窃听 .
解析:网络攻击:主动攻击(从入侵者角度) 和 被动攻击
拒绝服务:是指攻击者通过向目标服务器或网络发送大量的请求,使得目标系统资源耗尽&a…
基于深度学习的编程错误自动修复(Automated Code Repair Using Deep Learning)是一种利用深度学习技术自动检测、定位并修复代码中的错误的技术。它旨在减少开发者手动调试和修复代码的时间,并提高代码的质量和可靠性。这一技术在大规模软件开…