web前端之JavaScrip的笔试题
MENU
- Promise笔试题-02
- prototype和__proto__的笔试题
- JavaScript引用类型值值操和运算符优先级比较--笔试
- 原型与原型链--笔试-05
- 作用域-笔试
- 事件队列-笔试题
- JavaScript之变量提升-笔试题
- JavaScript之原型链--笔试题
Promise笔试题-02
console.log(1);
// 宏仁务 2
setTimeout(_ => {
console.log(2);
}, 1000);
async function fn() {
console.log(3);
// 宏仁务 3
setTimeout(_ => {
console.log(4);
}, 20);
// 结果为失败
// 所以 微任务 1
// 报错永远不会执行
return Promise.reject();
}
async function run() {
console.log(5);
await fn();
// 微任务 1
console.log(6);
}
run();
// 需要执行 150 MS 左右
for (let i = 0; i < 90000000; i++) {}
// 宏仁务 4
setTimeout(_ => {
console.log(7);
// 立即执行
new Promise(resolve => {
console.log(8);
// 微任务 5
resolve();
}).then(_ => {
console.log(9);
})
}, 0);
console.log(10);
// 1
// 5
// 3
// 10
// Uncaught (in promise) undefined
// 7
// 8
// 9
// 4
// 2
prototype和__proto__的笔试题
function Fn() {
// 代码字符串
// 谁 new 就是谁的私有属性
this.x = 100;
this.y = 200;
this.getX = function() {
console.log(this.x);
};
// 每个函数都有 prototype 对象
// 所以 prototype 是一个堆 Fn.prototype
// Fn.prototype 对象也带 __proto__ 属性
// 这个对象上有 constructor
// constructor 指向函数本身
};
// 把 getX 挂载到 Fn 的原型对象上
// 生成一个新的堆内存
// 属于公共属性
Fn.prototype.getX = function() {
console.log(this.x);
};
// 把 getY 挂载到 Fn 的原型对象上
// 生成一个新的堆内存
// 属于公共属性
Fn.prototype.getY = function() {
console.log(this.y);
};
// 括号可加可不不加
// 都是创建类的实例
// 创建实例对象 f1 / f2 (堆)
// 同时创建 x: 100 y: 200 getX: function() { ... }
// 都是这个实例的私有属性
// 通过 this 创建的变量和对象都属于私有属性
// 实例都带 __proto__ 属性
// __proto__ 所属类的原型 prototype
// 通过原型链往上找都属于 实例(Fn.prototype) 的共有属性
let f1 = new Fn();
let f2 = new Fn;
// Object内置类(堆)
// 有自己的 prototype 原型对象
// prototype 指向 Object.prototype 原型对象
// 有自己的 __proto__ 属性
// 有自己的 constructor 属性
// constructor 指向 Object
// Object.prototype 的 __proto__ 指向的是 null
// 实例指向的堆内存不同,如果自己私有就不会往原型类上查找
// 因为这个 getX 函数自己私有
// 所以两个实例的 getX 方法不相等
console.log(f1.getX === f2.getX); // false
// 因为 getY 这个函数不是自己私有
// 所以往原型链上查找,结果相等
// 原因就是他们的 __proto__ 都指向 Fn.prototype 原型对象
console.log(f1.getY === f2.getY); // true
// 通过原型链查找到的是公共的 getY
// 类似于 f1.getY === f2.getY
console.log(f1.__proto__.getY === Fn.prototype.getY); // true
// f1.__proto__.getX 找的是 Fn.prototype 公共属性
// f2.getX 因为自己私有
// 所以不相等
console.log(f1.__proto__.getX === f2.getX); // false
// f1.getX 属于自己私有的属性
// Fn.prototype.getX 本身就是公共属性
// 所以不相等
console.log(f1.getX === Fn.prototype.getX); // false
// f1 自己身上没有 constructor
// 往原型对象上查找
// 又因为 constructor 指向 函数本身
// 所以结果就是 Fn 函数
console.log(f1.constructor); // Fn 函数
// Fn.prototype 的 __proto__ 指向的是 Object.prototy
// 因为 Object.prototy 的 constructor 指向 Object 本身
// 所以是结果 Object
console.log(Fn.prototype.__proto__.constructor); // ƒ Object() { [native code] }
// f1.getX() 执行
// 并且 f1.getX 是属于自己私有
// 所以输出 100
// 函数执行前面有点
f1.getX(); // 100
// f1.__proto__.getX();
// 直接查找的是原型对象上的 getX()
// 原型上的是 console.log(this.x);
// 因为 f1.__proto__.getX(); getX() 前面有点
// 所以 相当于 f1.__proto__.x
// f1.__proto__.x 直接跳过自己(f1 实例对象(堆))往原型对象上查找
// 此时原型对象上也没有,再往 Object.prototype 对象上查找
// Object 对象上也没有
// 最后得到的是 undefined
f1.__proto__.getX(); // undefined
// 与 f1.getX(); 相同
f2.getY(); // 200
// Fn.prototype.getY();
// 直接查找的是原型对象上的 getY()
// 原型上的是 console.log(this.y);
// 因为 Fn.prototype.getY(); getY() 前面有点
// 所以 相当于 Fn.prototype.y
// Fn.prototype.y 直接跳过自己(f2 实例对象(堆))往原型对象上查找
// 此时原型对象上也没有,再往 Object.prototype 对象上查找
// Object 对象上也没有
// 最后得到的是 undefined
Fn.prototype.getY(); // undefined
JavaScript引用类型值值操和运算符优先级比较–笔试
let a = { n : 1 };
let b = a;
a.x = a = { n: 2 };
// 如果改为这样
// a = a.x = { n: 2 };
// 结果还是一样
// JavaScript 中点(.)比 等号 (=) 的优先级高
console.log(a.x); // undefined
// a.x = a = { n: 2 };
// 这段代码可以写成这样子
// a.x = { n: 2 };
// a = { n: 2 };
// 因为 a 是引用类型数据。
// 所以当 a.x = { n: 2 };时引用值的地址改变;
// 此时全局的 let a = { n: 1, x: { n: 2 } };
// 接着又执行 a = { n: 2 };时 a 引用地址已经改变。
// 最后输出的结果就是 : undefined
console.log(b.x); // { n: 2 }
// 经过上面 a 的操作,
// 全局的 a 值已经变为 a = { n: 1, x: { n: 2 } };
// 而此时 b 引用的地址一直没有改变
// 所以输出结果为 { n: 2 }
原型与原型链–笔试-05
function A() {};
A.prototype.n = 1;
var b = new A(); // b 实例对象已经建立原型连接
// 原型对象指向被改变,不会切断 b 实例对象的的指向
A.prototype = {
n: 2,
m: 3
};
var c = new A(); // c 实例对象将根据新的原型建立连接
console.log(b.n, b.m); // 1 undefined 这里拿到是改变 prototype 之前的堆数据
console.log(c.n, c.m); // 2 3 这里拿到是改变 prototype 之后的堆数据
// 此题生成了两个堆内存
// 并且两个堆内存都有自己的实例存储 => b c
作用域-笔试
var a = 0,
b = 0;
function A(a) {
// A(1)执行
// 1.A函数被重置为
// function A(b) {
// console.log(a + b++);
// };
// 2.执行打印console.log(a++),
// 因为此时的a是形参,形参的值是传入的1,
// 所以打印1,而且形参a执行了++,此时值为2
A = function (b) {
// A(2)调用情况
// 这个a采用的是闭包中的a,而不是全局中的a,
// 所以是2,b是形参也是2,所以打印的是4
// b使用的是传入的形参而不是全局中的b
console.log(a + b++);
};
// 调用函数A(1)的时候执行这一行代码,
// 并且把函数重置
console.log(a++);
};
A(1);
// 1
A(2);
// 4
事件队列-笔试题
示例-1
setTimeout(() => {
console.log(1);
}, 20);
console.log(2);
setTimeout(() => {
console.log(3);
}, 10);
console.log(4);
// console.time('time');
for (let i = 0; i < 90000000; i++) {
// 900000 5 个 0:2.57421875 ms 左右
// 9000000 6 个 0:12.625 ms 左右
// 90000000 7 个 0:116.13525390625 ms 左右
// 900000000 8 个 0:525.622314453125 ms 左右
// 9000000000 9 个 0:9807.490966796875 ms 左右
// 90000000000 10 个 0:循环不出来了
}
// console.timeEnd('time');
console.log(5);
setTimeout(() => {
console.log(6);
}, 8);
console.log(7);
setTimeout(() => {
console.log(8);
}, 15);
console.log(9);
// 2 4 5 7 9 3 1 6 8
循环的时间都超过了所有定时器的时间,在宏仁务中,定时器会按照从上到下的顺序执行,不再按照设置的时间长短来执行。
示例-2
console.log(1);
setTimeout(()=>{
console.log(2);
}, 50);
console.log(3);
setTimeout(()=>{
console.log(4);
while(1 === 1) {};
// 遇到死循环,
// 所有代码执行都是在主栈中执行,
// 主栈永远结束不了,
// 后面啥都不干
}, 0);
console.log(5);
// 1 3 5 4
示例-3
console.log(1);
// 宏仁务
setTimeout(function () {
console.log(2);
}, 0);
// 微任务
Promise.resolve().then(function () {
console.log(3);
}).then(function () {
console.log(4);
});
console.log(5);
// 1 5 3 4 2
JavaScript之变量提升-笔试题
1、自执行函数
var a = 10;
(function a() {
console.log(a);
a = 20;
console.log(window.a);
var a = 30;
console.log(a);
// 等同于
// 内部作用域
// var a; // 声明未赋值,结果为 undefined
// console.log(a); // undefined
// a = 20; // 内部作用域的a赋值为20
// console.log(window.a); // window中a的值依然是10
// a = 30; // 内部作用域的a赋值为30
// console.log(a); // 打印的是内部作用域中的a值为30
})();
2、变量提升与是否进入判断无关
var name = '张三';
function fn() {
if (typeof name === 'undefined') {
var name = '李四';
// 变量提升与是否进入判断无关
// 无论是否进入判断,变量都会提升
// 所以typeof nema的结果为'undefined'
console.log('辛苦了:' + name);
// 辛苦了:李四
} else {
console.log('吃饭没:' + name);
};
};
fn();
3、形参、未定义赋值
var a = 10,
b = 20,
c = 30;
function fn(a) {
// 形参即是定义在函数中的变量
a = 1;
var b = 2;
c = 3;
// 给未定义的变量强行赋值,
// 变量会挂载到全局
};
fn(100);
console.log(a, b, c);
// 10 20 3
4、in关键字、变量提升与判断无关
// ("a" in window) in 关键字查找window对象中是否存在变量a
// "a" in window成立了,所以这个条件不执行
if (!("a" in window)) {
var a = 10;
};
console.log(a);
// undefined
5、形参、||表达式赋值
var fn = 'hello';
(function (fn) {
// 定义形参即是定义了变量
// 因为形参有对应的实参
// 所以值为'hello'
console.log(fn);
// hello
// 同一作用域内,可以使用var定义多个同名变量
// 此处定义的fn变量会覆盖形参变量
// 并且赋值为fn
// ||前有值所以不往后执行
// 所以赋值为'hello'
var fn = fn || 'world';
console.log(fn);
// hello
})(fn);
console.log(fn);
// hello
6、函数提升的优先级高于一切
var n = 10;
function fn(n) {
console.log(n);
// ƒ n() { }
var n = 20;
console.log(n);
// 20
function n() { };
console.log(n);
// 20
};
fn(n);
console.log(n);
// 10
7、函数提升高于一切、重新赋值
function fn(fn) {
console.log(fn);
// ƒ fn() {
// console.log(fn);
// }
var fn = 20;
console.log(fn);
// 20
function fn() {
console.log(fn);
};
};
fn(30);
var fn = 10;
console.log(fn);
// 10
8、总结
变量的提升是JavaScript的默认行为,它会将所有变量声明移动到当前作用域的顶部,并且可以在声明之前使用变量。初始化不会被提升(赋值留在原地),提升仅作用于变量的声明。
JavaScript之原型链–笔试题
1、基础示例
Professor.prototype.tSkill = 'JavaScript';
function Professor() {}
var professor = new Professor();
Teacher.prototype = professor;
function Teacher() {
this.mSkill = 'html';
}
var teacher = new Teacher();
Student.prototype = teacher;
function Student() {
this.pSkill = 'css';
}
var student = new Student();
console.log(student);
// Student {pSkill: 'css'}
console.log(student.tSkill);
// JavaScript
console.log(student.mSkill);
// html
console.log(student.pSkill);
// css
原型链的顶端是
Object.prototype
Object.prototype
下保存了toString()
2、笔试题——1
Professor.prototype.tSkill = 'JavaScript';
function Professor() {}
var professor = new Professor();
Teacher.prototype = professor;
function Teacher() {
this.mSkill = 'html';
this.success = {
alibaba: '28',
tencent: '30'
};
}
var teacher = new Teacher();
Student.prototype = teacher;
function Student() {
this.pSkill = 'css';
}
var student = new Student();
student.success.baidu = '100';
student.success.alibaba = '29';
console.log(teacher);
// Professor {mSkill: 'html', success: {… }}
// mSkill: "html"
// success: {alibaba: '29', tencent: '30', baidu: '100'}
// [[Prototype]]: Professor
console.log(student);
// Student {pSkill: 'css'}