-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
10 - JS 2.0 #10
Comments
2. es5 / es6 继承除了写法上 有什么其他区别吗?1. 🔥 继承差异es5 继承利用 Child.proto === Function.prototypefunction Parent () {}
function Child () {}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
const c = new Child()
/**
* 实例对象
* __proto__: 普通对象 / 函数对象
* prototype: 只有函数对象里才有
* 实例对象__proto__ 指向 prototype
*/
c.__proto__ === Child.prototype // true
Child.__proto__ === Function.prototype // true
Child.__proto__ === Parent.__proto__ // true es6 Child.proto === Parentclass Parent {}
class Child extends Parent{ constructor (props) { super(props) } }
const c = new Child()
// 直接寻址方式
Child.__proto__ === Parent 2. 🔥 this 时机不同
|
3. 三个判断数组的方法 优劣势?
// 1. [所有数据类型都能判断]
Object.prototype.toString.call([1, 2]) // ['object Array']
// 2. 实例对象 是否是 该类 __proto_ 指向 Class.prototype
// 在原型链上是否能找到该原型, [只能判断对象类型]
[1, 2, 3] instanceof Array // true
[1, 2, 3] instanceof Object // true
// 3. 新增方法, 当浏览器不支持则用Object.prototype.toString.call判断
Array.isArray([1, 2, 3]) // true |
4. 模块化 Common.js / es6模块本质: 管理文件 es6 module vs common.js输出不同
加载方式不同
|
5. let / const 不挂载到window下, 那是去哪儿了?let a = 1
const b = 2
var c = 3 // 其实是挂载到了window window.c = 3
// 类似函数块级作用域, 外层window无法访问到
(function () {
var a = 1
var b = 2
})() |
6. 值输出?🔥非匿名函数自执行, 函数名只读 // 第一道题
var b = 10; // 在window下
// 🔥非匿名函数自执行, 函数名只读
(function b() {
b = 20;
// 没有var说明 在作用域链上找b, 找到function b(){}
// b函数相当于const, 内部是无法赋值的, 所以无效赋值
console.log(b) // 在作用域链上 最近找到的是 🔥输出function b
console.log(window.b) // 🔥输出10
})()
// 第二道题
var b = 10;
(function b() {
'use strict'
b = 20 // 报错 b找到了function b, 相当于const类型, 严格模式下直接报错
console.log(b)
})()
// 第三道题
var b = 10; // 在window下
(function a() {
b = 20; // 没有var说明, 都在window下 window.b = 20
console.log(b) // 所以输出的是 20
})()
// 第四道题
var b = 10;
(function b() {
window.b = 20;
console.log(b); // [Function b]
console.log(window.b); // 20
})();
// 第五道题
var b = 10;
(function b() {
var b = 20; // 内部变量
console.log(b); // 20
console.log(window.b); // 10
})(); |
7. 值输出?var a = 10;
(function () {
console.log(a)
a = 5
console.log(a)
console.log(window.a)
var a = 20;
console.log(a)
})()
/**
* 输出: undefined -> 5 -> 10 -> 20
* 函数体内, var a = 20 声明提升
* var a = undefined;
* console.log(a) // undefined
a = 5 // 赋值 没有定义? 会在作用域链上找, 是否声明, 没有再往上找
console.log(a) // 5
console.log(window.a) // 10
a = 20; // 赋值
console.log(a) // 20
*/ var a = 123;
(function(){
console.log(a)
a = 456
}());
console.log(a)
// 输出 123, 456
// 局部值, 全局无法访问
(function(){
var a = 456
}());
console.log(a) // Error: a is not defined
// 当前作用域无该值, 则挂载到window下
(function(){
a = 456
}());
console.log(a) // 456 |
8 - 改造 让其打印出10 或 20var b = 10;
(function b(){
b = 20;
console.log(b);
})(); var b = 10;
(function b(){
b = 20; // 无效赋值, 在作用域上找到了function b, 因为是自己运行, 只读
console.log(this.b) // this指向window
console.log(window.b); // 10
})();
var b = 10;
(function b(){
var b = 20;
console.log(b); // 20
})();
var b = 10;
(function b(){
b = 20;
console.log(b); // 20
var b = 0
})();
})(); |
9 - [3, 15, 8, 29, 102, 22].sort();?[3, 15, 8, 29, 102, 22].sort()
// 默认是按照字母数组顺序排序的 [102, 15, 22, 29, 3, 8]
[3, 15, 8, 29, 102, 22].sort((a, b) => a - b) // a > b 位置交换 其他位置不变
// [3, 8, 15, 22, 29, 102]
[3, 15, 8, 29, 102, 22].sort((a, b) => b - a)
// [102, 29, 22, 15, 8, 3] 10 - call 和 apply 的区别是什么,哪个性能更好一些?
11 - 值输出?var obj = {
'2': 3,
'3': 4,
'length': 2,
'splice': Array.prototype.splice,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj) // [, , 1, 2]
/**
* push做了两件事情
* 1. push数据到数组末尾
* 2. 返回数组新长度
*
* 1. push(1): obj[2] = 1, obj.length += 1
* 2. push(2): obj[3] = 2, obj.length += 1
* 因为数组没有设置 0, 1 下标值, 所以是empty打印
* 类数组返回: [, , 1, 2]
* Object[
* 2: 1,
* 3: 2,
* 'length': 2,
'splice': Array.prototype.splice,
'push': Array.prototype.push
* ]
*/ |
13 - a.b.c.d 和 a['b']['c']['d'],哪个性能更高?从AST来看 a['b']['c']['d'] 比 a.b.c.d 会解析 [ ]。解析的话 前面比后面更好些。所以性能更高。 14 - 箭头函数 ?
15 - 为什么普通 for 循环的性能远远高于 forEach 的性能,请解释其中的原因?对for来说 最原始的循环方式
forEach((value, index) => {}) 需要额外的函数调用 和 内存空间 |
16 - 值?// 例子1 ---------------------
var a={}, b='123', c=123;
a[b]='b';
a[c]='c';
console.log(a[b]);
/**
* a[b]='b'; a: { '123': 'b' }
* a[c]='c'; c=123 对于Object来说, 被转换成string类型
* a: { '123': 'c' }
* 输出: 'c'
*/
// 例子2 ---------------------
var a={}, b=Symbol('123'), c=Symbol('123');
a[b]='b';
a[c]='c';
console.log(a[b]); // b
console.log(a[c]); // c
/**
* Symbol 是唯一, 任何类型值都不相等, 前一个不会被覆盖掉
* a = { Symbol(123): 'b' }
* a = { Symbol(123): 'b', Symbol(123): 'c' }
* 输出: 'b', 'c'
*/
// 例子3 容易错 !!! 多看 ---------------------
var a={}, b={key:'123'}, c={key:'456'};
a[b]='b';
a[c]='c';
console.log(a[b]);
/**
* 这种思路是错的 ❌
* a: { '{key:'123'}': 'b' }
* a: { '{key:'123'}': 'b', '{key:'456'}': 'c' }
*
* 除了string 和 Symbol外, 会调用toString()
* {key:'123'}.toString() 会变成 '[object Object]'
* {key:'456'}.toString() 也会变成 '[object Object]'
* [1, 2, 3].toString() 变成 "1,2,3"
* a: { [object Object]: 'c' }
* 输出 c
*/ |
17 - var、let 和 const 区别的实现原理是什么?1. 声明 / 初始化 / 赋值
2. 内存分配
|
18 - 值结果?function changeObjProperty(o) {
// o是个引用, 相当于 传了 webSite
// webSite.siteUrl = 'baidu'
o.siteUrl = "http://www.baidu.com"
o = new Object() // o = {} 新的对象, 不同于传参的o
o.siteUrl = "http://www.google.com"
return o
}
let webSite = new Object();
let twowebSite = changeObjProperty(webSite);
console.log(webSite.siteUrl); // baidu
console.log(twowebSite.siteUrl); // google let a = 1
// 基本类型是copy, 里面影响不了外面
function changeObjProperty(a) {
console.log(a) // 1
a = "http://www.baidu.com"
console.log(a) // http://www.baidu.com
}
changeObjProperty(a)
console.log(a) // 1 |
19 - 值结果?function Class () {}
Class.a = xxx // 静态方法
Class.prototype.b = xxx // 原型方法
class A {
static a () {} // 静态方法 是类可以直接访问到
b () {}
} function Foo () {
// 构造函数
Foo.a = function() { // 静态方法 a
console.log(1)
}
this.a = function() {
console.log(2)
}
}
console.log(Foo.a) // undefined, Foo.a(1) 是在构造函数里的创建
// 挂在原型方法
Foo.prototype.a = function() {
console.log(3)
}
console.log(Foo.prototype.a) // Foo.prototype.a(3)
console.log(Foo.a) // undefined
// 直接挂在方法
Foo.a = function() {
console.log(4)
}
console.log(Foo.a) // Foo.a(4)
Foo.a(); // 4
let obj = new Foo();
obj.a(); // 2 在构造函数方法里定义 this.a
// 实例对象有私有属性a 和 原型链属性a, 私有优先级更高
// 私有a 会把 共有给覆盖掉
Foo.a(); // 1 构造函数执行 (new Foo()) 已经替换了 4的那个输出 |
20 - 值结果?// String('11') 返回的是 '11'
'11' === String('11') // true
// == 做了隐式转换, 调用toString
// 类似: String('11') == new String('11').toString()
// new String('11') 返回的是个对象 { 0: 1, 1: 1 }
String('11') == new String('11') // true 值相同
String('11') === new String('11') // false 21 - 值结果?var name = 'Tom';
(function() {
// var name = 'Jack'; 会提升到这里
console.info('name', name); // undefined
console.info('typeof name', typeof name); // undefined
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name); // Goodbye Jack
} else {
console.log('Hello ' + name);
}
})(); var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
let name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
// Hello Tom var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
name = 'Jack'; // 未声明 会被提升到全局作用域中, 没有变量提升效果 window.name 会访问到
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
// Hello Tom |
22 - 值结果?1 + "1"
2 * "2"
[1, 2] + [2, 1]
"a" + + "b"
/**
* 加法: 有一个是string, 都转为string
* "1" + 1 = '11' "1" + "1" = '11'
* 乘法: 都转为number
* '2' * '3' = 6 '2' * 3 = 6
* 对象: 先转换为 toString
* [1, 2].toString() = '1, 2'
* [2, 1].toString() = '2, 1'
*
* + '1' string 转为 number: 1
* + 'a' string 转为 number: NaN
*
* 结果:
* '11'
* 4
* '1, 22,1'
* 'aNaN'
*/ |
23 - 值结果?
function wait() {
return new Promise(resolve => setTimeout(resolve, 10 * 1000))
}
async function main() {
console.time();
const x = wait(); // 已经执行promise
const y = wait(); // 已经执行promise
const z = wait(); // 已经执行promise
await x;
await y;
await z;
console.timeEnd();
}
main();
function wait() {
return new Promise(resolve =>
setTimeout(resolve, 10 * 1000)
)
}
async function main() {
console.time();
await wait();
await wait();
await wait();
console.timeEnd();
}
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
1. ['1', '2', '3'].map(parseInt) what & why ?
The text was updated successfully, but these errors were encountered: