Open george-es opened 3 years ago
function mySetInterVal(fn, a, b) {
this.count = 0
this.a = a
this.b = b
this.timer = -1
this.start = () => {
return () => {
this.timer = setTimeout(() => {
fn()
this.count++
this.start()
}, this.a + this.count * this.b)
}
}
this.stop = () => {
clearTimeout(this.timer)
this.count = 0
}
}
var t = new mySetInterVal(() => {console.log('test')},1000, 2000 );
t.start();
t.stop();
function fibonacciIterative(n) {
if (n < 1) return 0;
if (n <= 2) return 1;
let fibNMinus1 = 0;
let fibNMinus2 = 1;
let fibN = n
for (let i = 2; i < n; i++) {
fibN = fibNMinus1 + fibNMinus2
fibNMinus1 = fibNMinus2
fibNMinus2 = fibN
}
return fibN
}
1)React 16.x的三大新特性 Time Slicing, Suspense,hooks
2)React16.8
3)React16.9
4)React16.13.0
防抖:某个事件频繁触发,若一段事件后,该事件没有触发,则执行事件函数,整个过程事件只触发一次
function debounce(func, wait) {
let timer = null
return () => {
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(() => func.apply(this, arguments), wait)
}
}
节流:某个事件频繁触发,事件并不会按照次数进行触发,而会按照固定的时间频率触发,整个过程,事件触发多次
function throttle(func, wait) {
let timer = null
return () => {
if(!timer) {
timer = setTimeout(() => {
func.apply(this, argument)
timer = null
}, wait)
}
}
}
什么是闭包?
函数执行后返回结果是一个内部函数,并被外部变量所引用,如果内部函数持有被执行函数作用域的变量,即形成了闭包。
闭包的原理?
闭包的执行分为两个阶段,预编译阶段和执行阶段
利用了函数作用域链的特性,一个函数内部定义的函数会将包含外部函数的活动对象添加到它的作用域链中,函数执行完毕,其执行作用域链销毁,但因内部函数的作用域链仍然在引用这个活动对象,所以其活动对象不会被销毁,直到内部函数被烧毁后才被销毁。
优点:
缺点:
应用场景
var Yideng = (function() {
// 这样声明为模块私有变量,外界无法直接访问
var foo = 0;
function Test() {}
Test.prototype.bar = function bar() {
return foo;
};
return Test;
}())
function Closure(num) {
return () => {
console.log(num)
}
}
for (var i = 0; i < 10; i++) {
setTimeout(Closure(i))
}
JS 数据类型分为两类,基础类型和引用类型
基础类型:string,number,boolean,undefined,null,symbol,bigint
复杂类型:function,object
区别:
BigInt 是一种内置对象,它提供了一种方法用来表示超过 Number 类型最大范围的数(2 ^ 53 - 1),BigInt
可以表示任意大的整数。
BigInt 也称为 JS 中的任意精度整型,可表示任意精度的整数值
可以用在一个整数后加 n 的方式定义 BigInt,或者用 BigInt()
const bigNum = 10n
const bn = BigInt('10')
解决了什么问题?
如何使用
Number 基本运算符都可以使用(除了 + ),但和 Number 类型不能相互加减,不能使用 Math 函数的方法
-10n // -10n
10n + 10n // 20n
10n * 10n // 100n
10n / 10n // 1n
10n + 10 // TypeError: Cannot mix BigInt and other types
Number(10n) // 10
10n == 10 // true
10n === 10 // false
!!0n // false
!!1n // true
let n = 10n
console.log(++n) // 11n
console.log(--n) // 9n
Math.max(1n, 2n, 3n) // TypeError: Cannot convert a BigInt value to a number
相同点
不同点
null 是一个表示”无“的对象,转为数值时为 0,undefined 是一个表示”无“的原始值,转数值时为 NaN
Number(null) // 0
Number(undefined) // NaN
null 表示”没有对象“,即该处不应该有值,
作为函数的参数,表示该函数的参数不是对象
作为对象原型链的终点
undefined 表示”缺少值“,此处应该有一个值,但是还没有定义
变量声明了,但没有赋值时,就等于 undefined
调用函数时,应该提供的参数没有提供,该参数等于undefined。
函数没有返回值时,默认返回undefined。
对象没有赋值的属性,该属性的值为undefined。
typeof
基本数据类型除了 null 以外都可以获得正确结果
引用类型除了 function 外,都为 object
function 返回 function
null 返回 object
instanceof
a 是 A 的对象,A -> B -> C 是一条原型链,那么
a instanceof A // true
a instanceof B // true
a instanceof C // true
只能判断引用类型,基本类型不可以
'1' instanceof String // false
所有对象类型的 instanceof Object 都为 true,a 为一个对象
a instanceof Object // true
// 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例
function Aoo(){}
function Foo(){}
Foo.prototype = new Aoo();//JavaScript 原型继承
var foo = new Foo();
console.log(foo instanceof Foo)//true
console.log(foo instanceof Aoo)//true
因此instanceof 只能用来判断两个对象是否属于实例关系,并不能判断一个对象具体属于那种类型
内部原理
function instance_of(L, R) {
const O = R.prototype
L = L.__proto__
while (true) {
if (L === null) {
return false
}
if (L === O) {
return true
}
L = L.__proto__
}
}
constructor
用于判断实例的数据类型,和 instanceof 不同的地方在于它不会沿着原型链查找
要注意的是
toString 精准判断对象类型
toString() 能够返回 [ object Object ],对于其他对象,则要通过 call / apply 来调用才能返回正确的类型信息。
Object.prototype.toString.call(xxx)
toString 方法对于所有基本的数据类型都能进行判断,即使是 null 和 undefined,但是它无法获取到实例是属于那个构造函数的。
isArray()
用于判断对象是否为数组
所以说typeof,toString 检测的是实例与数据类型之间的关系,instanceof 和 constructor 检测的是实例与构造函数之间的关系。
常见的会转换成这几个类型 string,number,boolean,
string
toString():除了 null 和 undefined 都可以正常转换
String():可以处理任何的值,如果在处理对象上,会默认调用 toString 方法
console.log(String({valueOf: () => 'aaa'})) // [object Object]
console.log(String({valueOf: () => '123'})) // [object Object]
console.log(String({valueOf: () => 1})) // [object Object]
console.log(String({toString: () => 1})) // ’1‘
console.log(String({toString: () => '123'})) // '123'
console.log(String({toString: () => 'aaa'})) // 'aaa'
number
console.log(parseInt(' 123')); // 123
console.log(parseInt('aa123')); // NaN
console.log(parseInt('123aaa')); // 123
console.log(parseInt('-123aaa')); // -123
console.log(parseInt('- 123aaa')); // NaN
console.log(parseInt('1123ff23')); // 1123
console.log(parseInt('1123.123123')); // 1123.123123
console.log(parseInt('1123', 8)); // 1123
console.log(parseInt(' 123')); // 123
console.log(parseInt('aa123')); // NaN
console.log(parseInt('123aaa')); // 123
console.log(parseInt('-123aaa')); // -123
console.log(parseInt('- 123aaa')); // NaN
console.log(parseInt('1123ff23')); // 1123
console.log(parseInt('1123.123123')); // 1123
console.log(parseInt('1123', 8)); // 595
console.log(Number(true)); // 1
console.log(Number(123)); // 123
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(Number('123')); // 123
console.log(Number('123.123')); // 123.123
console.log(Number('0x99')); // 153
console.log(Number('')); // 0
console.log(Number('asdf2213')); // NaN
console.log(Number({})); // NaN
console.log(Number([1, 2, 3])); // NaN
console.log(Number([3])); // 3
console.log(Number(Symbol(123))); // TypeError
console.log(Number({valueOf: () => 'aaa'})) // NaN
console.log(Number({valueOf: () => '123'})) // 123
console.log(Number({valueOf: () => 1})) // 1
console.log(Number({toString: () => 1})) // 1
console.log(Number({toString: () => '123'})) // 123
console.log(Number({toString: () => 'aaa'})) // NaN
这里要注意的是
如果是数组,且大于一个元素会返回 NaN,如果只有一个元素,会返回该元素,
如果是对象,会在对象中寻找是否有 valueOf(),有则执行,输出值,没有就执行 toString(),在尝试 Number 转换,如果都无法获取数值,返回 NaN
boolean
就一种方式 Boolean()
类型 | true | false |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | ""(空字符串) |
Number | 任何非零数字值(包括无穷大) | 0 和 NaN |
Object | 任何对象 | null |
Undefined | n/a | undefined |
Function | true | n/a |
n/a :表示不存在这种情况
__proto__
属性,属性值是个普通对象。__proto__
属性值指向它的构造函数 prototype 属性值,即 obj.__proto__ === Object.prototype
。__proto__
中寻找。原型链:将原型对象连起来就是原型链
var new = (func) => {
var o = Object.create(func.prototype)
var k = func.call(o)
if(typeof k === 'object') {
return k
} else {
return o
}
}
词法作用域:函数作用域在函数定义的时候就决定了
动态作用域:函数作用域在函数调用时候才决定的
分类
JS 的作用域分三类,全局作用域,函数作用域,以及 es6 的块级作用域
变量提升,函数提升
函数表达式
const func = function() {}
变量提升是提升所在作用域的最顶端而不是全局的最顶端
同名的函数声明和变量声明,采用忽略原则,函数提升优先变量提升
console.log(typeof a) // function
var a = 1
function a() {console.log('hello world')}
foo() // 2
function foo() {
console.log(1)
}
function foo() {
console.log(2)
}
var a = 1
var a = 2
// 解析
var a
var a // 被忽略
a = 1
a = 2
console.log(a) // undefined
if(true) {
function a() {}
}
function foo(a) {
console.log(a) // 3
var a = 2
console.log(a) // 2
}
foo(3)
// 解析
function foo(a) {
var a = 3
console.log(a)
var a
a = 2
console.log(a)
}
访问机制
执行上下文建立分两个过程
变量对象的创建,包括参数,函数内部的变量声明等
创建作用域链,就是 scope chain 的形成
this 的确定
当访问一个变量时,会在当前作用域下寻找,若当前未找到对应的变量,则会沿着作用域链寻找
全局调用普通函数
构造函数
对象方法
如果函数作为对象方法是,方法中的 this 指向该对象,如果在对象方法中定义函数,情况就不一样的了
var obj = {
x: 10,
foo: function() {
console.log(this) // obj 对象
function f() {
console.log(this) // window
console.log(this.x) // undefined
}
const t = () => {
console.log(this) // obj 对象
}
t()
f()
}
}
obj.foo()
虽然 f 在函数内部定义,但是它是各普通函数,因此指向 window,箭头函数则是由父级上下文决定的因此是 obj
构造函数 prototype 属性
构造函数中,this 指向 new 出来的对象,在整个原型链中,任何一个地方调用 this,依旧指的是 new 出来的对象
函数用 call,apply 或者 bind 调用
当一个函数被 call,apply 或者 bind 调用时,this 的值就取传入对象的值
DOM event this
在一个 HTML DOM 事件处理程序中,this 始终指向这个处理程序所绑定的 HTML DOM 节点
箭头函数中 this
箭头函数内部的 this 是词法作用域,由上下文决定,也就是说,箭头函数中的 this 指向的是外层的调用者
call,apply,bind 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响
延迟函数 setTImeout & setInterval
非箭头函数情况下,延迟函数中的 this 是指向window的,箭头函数情况下,如果有外层包裹延迟函数,则箭头函数中 this 指向外层函数, 若没有,指向 window
程序运行需要用到内存,只要程序提出需求,操作系统或运行时,就必须提供内存。
对于持续运行的服务进程,必须及时释放不再用到的内存,否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。
不再用到的内存,没有及时释放,就叫内存泄漏(memory leak)
最常用的方法叫"引用计数",语言引擎有一张"引用表",保存了内存里面所有的资源的引用次数,如果一个值的引用次数是 0 ,就表示这个值不再用到,因此可以将这块内存释放。
如果一个值不再需要,引用数却不为0,垃圾回收机制无法释放这块内存,从而导致内存泄漏。
譬如说
const arr = [1,2,3,4]
console.log('hello world')
定义了一个 arr,会占用内存,此时引用计数为 1
const arr = [1,2,3,4]
console.log('hello world')
arr = null
此时将它置为 null,就解除了 arr 的引用,此时引用计数为 0,内存就释放出来了。
因此,并不是说有了垃圾回收机制,程序员就轻松了。还是需要关注内存占用:那些很占空间的值,一旦不再用到,你必须检查是否还存在对它们的引用。如果是的话,就必须手动解除引用。
怎样可以观察到内存泄漏呢?
经验是,如果连续五次垃圾回收之后,内存占用一次比一次大,就有内存泄漏。这就要求实时查看内存占用。
在 chrome 中,我们可以通过捕获观察内存是否平稳,如果逐渐升高代表泄漏了
全局变量
function foo(arg) {
bar = "some text"
}
这段代码在函数中定义了变量 bar,并赋值一段字符串,却没有在函数中声明,因此它就变成了全局变量,函数执行完毕后,该变量依旧可以被访问,其占用的内存不会被释放,从而导致内存泄漏。
因此在开发过程中要避免使用全局变量,除了污染全局作用域,还有内存泄漏
闭包(闭包本身没有错,是因为使用不当导致的内存泄漏)
由于闭包原因,执行完 foo() 后,依旧保留 a 变量的作用域,因此会造成内存
var theThing = null;
var replaceThing = function () {
var originalThing = theThing;
var unused = function () {
if (originalThing)
console.log("hi");
};
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage);
}
};
};
setInterval(replaceThing, 1000);
闭包的链表已经创建,每一个闭包作用域携带一个指向大数组的间接的引用,造成严重的内存泄漏。
解决: 去除unuserd函数或者在replaceThing函数最后一行加上 originlThing = null.
定时器和回调函数
var someResource = getData()
setInterval(function() {
var node = document.getElementById('Node')
if(node) {
node.innerHTML = JSON.stringify(someResource)
// 定时器没有清除
}
// node someResource 存储了大量数据 无法回收
},1000)
定时器完成工作后没有被删除,导致产生了大量的数据 node 对象,回调函数,无法回收,因此解决方案是在定时器完成工作的时候,手动清除定时器。
DOM 引用
var refA = document.getElementById('refA')
document.body.removeChild(refA); // dom删除了
console.log(refA, "refA"); // 但是还存在引用
// 能console出整个div 没有被回收
由于 refA 没有置为 null,保留了 DOM 节点的引用,导致 GC 没有回收。
try
里面放 return
,finally
还会执行,理解其内部机制try-catch-finally 内部机制
try 语句包含了由一个或多个语句组成的 try 块,和至少一个 catch 块或一个 finally块
三种形式
运行机制
function tryCatch() {
try {
console.log(1.1)
try {
console.log(2.1)
} finally {
console.log(2.2)
}
console.log('---')
} finally {
console.log(1.2)
}
}
tryCatch()
// output
1.1
2.1
2.2
---
1,2
function tryCatch() {
try {
console.log(1.1)
try {
throw new Error()
console.log(2.1)
} finally {
console.log(2.2)
}
console.log('---')
} catch (e) {
console.log('error')
} finally {
console.log(1.2)
}
}
tryCatch()
// output
1.1
2.2
error
1.2
try执行完后,才执行finally。或者try中产生了异常,会执行catch中的代码,最后执行finally的代码。但是切记:finally的代码,是在try或者catch代码块的return之前执行。
try和catch块return之前,会执行finally代码。然后执行finally之前,会暂时保存需要return的信息,执行完finally后,再return保存的信息。
function testReturn() {
let i = 1
try {
i++;
console.log("try:" + i)
return i
} catch (e) {
i++
console.log("catch:" + i)
return i
} finally {
i++
console.log("finally:" + i)
// return i
}
}
console.log(testReturn())
finally 一般不写 return 语句,如果写了返回值就是3
虽然 js 是单线程的,但是它可以执行同步和异步任务,这要归功于它的任务机制。同步任务不多解释,就是按照顺序去执行,而异步任务,是有一个优先级的,包括了宏任务和微任务。
宏任务:setTimeout,setInterval,setImmediate,I/O,UI,rendering
微任务:Promise(then,catch,finally),process,nextTick,MutationObserver
执行栈的执行逻辑是
先把所有的同步任务执行了
从宏任务头部去除一个任务执行
执行过程中遇到微任务将其添加到微任务队列中
宏任务执行完毕后,微任务的队列中是否存在任务,若存在,则挨个去执行,直到执行完毕
GUI 渲染,再回去开始心的宏任务,直到任务全部执行完
JS 包括核心(ECMAScript)、文本对象模型(DOM)、浏览器模型(BOM)
也就是说 EMACScript 来源于 JavaScript,又反向作为 JavaScript 的标准。
一拿到这个题,我立刻脱口而出,答案 1,2,3
,run 完后发现答案竟然是 [1, NaN, NaN]
带着疑虑,做出猜想,parseInt 可以接收 2 个参数,很可能就是第二个参数导致的,第二个参数传的是基数
于是把数加大,看能不能找出规律
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'].map(parseInt)
// [ 1, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 9, 11, 13 ]
就是基数搞的鬼,map 后,数组的下标成了基数,上面这行代码会被解析成
parseInt('1', 0) // 1
parseInt('2', 1) // NaN
parseInt('3', 2) // NaN
这时围绕着基数,在想,什么是基数呢?应该是进制数了,随后摸索了下 parseInt 的实现原理,这就涉及进制转换原理了
parseInt("11",2) // 返回 3 (2 + 1)
把 11 看成两个数 1 + 1,因为 1 都小于基数 2,所以 1 * 2^1 +1 * 2^0 = 2+1 = 3
parseInt("113",2) // 返回 3 (2 + 1)
由于 3 大于 2 不属于 2 进制数,因此只计算前两位 1 * 2^1 +1 * 2^0 = 2+1 = 3
parseInt("131",2) // 返回 2 (2)
由于 3 大于 2,因此计算规则是从第一个是2进制数的数开始到碰到第一个不是2进制数截止。
parseInt("311",2) // 返回 NaN
由于 3 大于 2 不属于 2 进制,所以不往后计算了
同理其他进制也是这样计算的
Set:它是一种数据结构,类似数组,里面的值都是唯一的,主要应用场景是数据重组。
4 个操作方法,add,delete,has,clear
4 种遍历方法,values,keys,entries,forEach
2 种转换方法:Array.from(),[... new Set()]
2 个属性:constructor,size
Map:也是一种数据结构,类似对象,和对象的区别在于,对象的键(key)只能是字符串,而 map 的键(key)可以是任意数据类型,主要应用场景是数据存储。
1 个属性,size
5 个操作方法,set,get,has,delete,clear
4 个遍历方法,keys,values,entries,forEach
1 种转换方法,[... new Map()]
WeakSet:和 Set 类似
区别在于
有 3 个方法
应用场景
存储 DOM 节点,不用担心节点移除后引发内存泄漏
WeakMap:和 Map 类似
区别在于
有 4 个方法
模块化主要作用是用来抽离公共代码,隔离作用域,避免变量冲突。
常用的模块化方案:
IIFE(自执行函数):使用自执行函数编写模块化,特点,在单独函数作用域中执行代码,避免变量冲突
(function() { })()
AMD:使用 requireJS 来编写模块化,特点,依赖必须提前声明好
define('./index.js',function(code) {})
CMD:使用 seaJS 来编写模块化,特点,支持动态引入依赖文件
define(function(require, exports, module) {
var indexCode = require('./index.js')
})
CommonJS:node 中自带模块化
特征函数:require、module.exports、exports
CommonJS 一般用在服务端或者 Node 用来同步加载模块,它对于模块的依赖发生在代码运行阶段,不适合在浏览端做异步加载。
var fs = require('fs')
ES Module:ES6 引入的模块化,支持 import 来引入另一个js
特征函数:import、export
ES6 模块化不是对象,import 会在 JS 引擎静态分析,在编译时就引入模块代码,而并非在代码运行时加载,因此也不适合异步加载。
import a from 'a'
不会的,它有独立作用域
let a = 10
console.log(window.a) // undefined
// 等同于
(function() {
var a = 10
})()
var b = 10
(function b() {
b = 20
console.log(b) // [function b]
console.log(window.b) // 10
})()
内部作用域,会先去查找是有已有变量 b 的声明,有就直接赋值 20,确实有,发现是具名函数,function b(){},拿此 b 做赋值,IIFE 无法进行赋值(内部机制,类似 const 定义的常量)所以无效
var a = 10;
(function () {
console.log(a) // 10
})()
这里会到外层去取
var a = 10;
(function () {
console.log(a) // undefined
a = 5
console.log(window.a) // 10
var a = 20
console.log(a) // 20
})()
// 一
var obj = {
'0': 10,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj); // { '0': 1, '1': 2, push: [Function: push], length: 2 }
// 二
var obj = {
'0': 10,
'length': 8,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj); // { '0': 10, '8': 1, '9': 2, length: 10, push: [Function: push] }
// 三
var obj = {
'0': 10,
'length': 8,
'splice': Array.prototype.splice,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
obj.splice(1, 1, 1)
console.log(obj); // {'0': 10, '1': 1, '8': 1, '9': 2, length: 10, splice: [Function: splice], push: [Function: push]}
push 这个方法如果对象上有 length 属性,length 属性会加 1 并且返回,若没有则创建它,这道题考的是类数组和 push 方法
箭头函数是普通函数的简写形式,有以下几点区别
__proto__
下面代码的输出是什么?
答案:
20
andNaN
解析:请注意,
diameter
是普通函数,而perimeter
是箭头函数。对于箭头函数,
this
关键字指向是它所在上下文(定义时的位置)的环境,与普通函数不同! 这意味着当我们调用perimeter
时,它不是指向shape
对象,而是指其定义时的环境(window)。没有值radius
属性,返回undefined
。下面代码的输出是什么?
答案:
TypeError
解析:
colorChange
方法是静态的。 静态方法仅在创建它们的构造函数中存在,并且不能传递给任何子级。 由于freddie
是一个子级对象,函数不会传递,所以在freddie
实例上不存在freddie
方法:抛出TypeError
。当我们这样做时会发生什么?
答案:Nothing, this is totally fine!
解析:这在
JavaScript
中是可能的,因为函数也是对象!(原始类型之外的所有东西都是对象)函数是一种特殊类型的对象。您自己编写的代码并不是实际的函数。 该函数是具有属性的对象,此属性是可调用的。
下面代码的输出是什么?
答案:TypeError
解析:您不能像使用常规对象那样向构造函数添加属性。 如果要一次向所有对象添加功能,则必须使用原型。 所以在这种情况下应该这样写:
这样会使
member.getFullName()
是可用的,为什么样做是对的? 假设我们将此方法添加到构造函数本身。 也许不是每个Person
实例都需要这种方法。这会浪费大量内存空间,因为它们仍然具有该属性,这占用了每个实例的内存空间。 相反,如果我们只将它添加到原型中,我们只需将它放在内存中的一个位置,但它们都可以访问它!所有对象都有原型?
答案:错误
解析:除基础对象外,所有对象都有原型。 基础对象可以访问某些方法和属性,例如
.toString
。 这就是您可以使用内置JavaScript
方法的原因! 所有这些方法都可以在原型上找到。 虽然JavaScript
无法直接在您的对象上找到它,但它会沿着原型链向下寻找并在那里找到它,这使您可以访问它。译者注:基础对象指原型链终点的对象。基础对象的原型是
null
。下面代码的输出是什么?
答案:["", "is", "years old"]
`Lydia
`21解析:如果使用标记的模板字符串,则第一个参数的值始终是字符串值的数组。 其余参数获取传递到模板字符串中的表达式的值!
sessionStorage 生命时长
答案:用户关闭选项卡时。
解析:关闭选项卡后,将删除存储在
sessionStorage
中的数据。如果使用localStorage
,数据将永远存在,除非例如调用localStorage.clear()
。下面代码的输出是什么?
答案:true
`true
false
`true解析:所有对象键(不包括
Symbols
)都会被存储为字符串,即使你没有给定字符串类型的键。 这就是为什么obj.hasOwnProperty('1')
也返回true
。上面的说法不适用于
Set
。 在我们的Set
中没有“1”
:set.has('1')
返回false
。 它有数字类型1
,set.has(1)
返回true
。下面代码的输出是什么?
答案:{ a: "three", b: "two" }
解析:如果对象有两个具有相同名称的键,则将替前面的键。它仍将处于第一个位置,但具有最后指定的值。
JavaScript全局执行上下文为你创建了两个东西:全局对象和this关键字.
答案:对
解析:基本执行上下文是全局执行上下文:它是代码中随处可访问的内容。
下面代码的输出是什么?
答案:456
解析:对象键自动转换为字符串。我们试图将一个对象设置为对象
a
的键,其值为123
。但是,当对象自动转换为字符串化时,它变成了
[Object object]
。 所以我们在这里说的是a["Object object"] = 123
。 然后,我们可以尝试再次做同样的事情。c
对象同样会发生隐式类型转换。那么,a["Object object"] = 456
。然后,我们打印
a[b]
,它实际上是a["Object object"]
。 我们将其设置为456
,因此返回456
。下面这些值哪些是假值?
答案:
0
,''
,undefined
解析:
JavaScript
中只有6个假值:undefined
null
NaN
0
''
(empty string)false
函数构造函数,如
new Number
和new Boolean
都是真值。下面代码的输出是什么?
答案:string
解析:
typeof 1
返回"number"
.typeof "number"
返回"string"
下面代码的输出是什么?
答案:
1
undefined
2
解析:
catch
块接收参数x
。当我们传递参数时,这与变量的x
不同。这个变量x
是属于catch
作用域的。之后,我们将这个块级作用域的变量设置为
1
,并设置变量y
的值。 现在,我们打印块级作用域的变量x
,它等于1
。在
catch
块之外,x
仍然是undefined
,而y
是2
。 当我们想在catch
块之外的console.log(x)
时,它返回undefined
,而y
返回2
。JavaScript中的所有内容都是?
答案:原始或对象
解析:
JavaScript
只有原始类型和对象。原始类型是
boolean
,null
,undefined
,bigint
,number
,string
和symbol
。