代码及编程题「每题4分」

  1. alert(3);
    1. let num = parseFloat('width:100px');
    2. if(num == 100){
    3. alert(1);
    4. }else if(num == NaN){
    5. alert(2);
    6. }else if(typeof num == 'number'){
    7. alert(3);
    8. }else{
    9. alert(4);
    10. }
    2.NaNTencentnull9false
    let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
    console.log(result);
    //100+1+21.2+0==>100+1+21.2+0+=undefined >NaN+"Tencent"+"" =>"NaNTencent+""+null+9+false
    
    3.
    https://www.yuque.com/caoxiaosong-iq5i9/vc73ek/zsxy6v
    a.x=undefined
    {n: 1, x: {n:2}}
    var a = {n: 1};
    var b = a;
    a.x = a = {n: 2};
    console.log(a.x);
    console.log(b);
    
    4.
    // a等于什么值,会使条件成立「两种方案」
    var a = ?;
    if (a == 1 && a == 2 && a == 3) {
    console.log('OK');
    }
    
    var a = {
          n:0,
          toString:function(){
               return ++this.n;
          }
       };
       if (a == 1 && a == 2 && a == 3) {
           console.log('OK');
    }
    

5.
[27, NaN, 1, 1, 27]

// 输出arr的结果
let arr = [27.2, 0, '0013', '14px', 123];
arr = arr.map(parseInt);
//[radix]不设置(或者写的是零):正常都是按照10处理的

6.

/*
下面代码是否可以,每隔1000MS依次输出 0 1 2 3 4 5 ?
如果不可以,说明为啥?以及如何解决?「三种方案处理」
*/
for (var i = 0; i < 5; i++) {
    setTimeout(function () {
console.log(i);
    }, (i + 1) * 1000);
}


//=>setTimeOut 传递第三个参数
for (var i = 0; i < 5; i++) {
   setTimeout(function (i) {
        console.log(i);
   }, 1000, i);
}

7.
alert(1)
alert(4)

let a=0,
    b=0;
function A(a){
    A=function(b){
        alert(a+b++);
    };
    alert(a++);
}
A(1);
A(2);

8.
https://www.yuque.com/caoxiaosong-iq5i9/vc73ek/rxc5di
undefined
ƒ foo() {}
1
ƒ foo() {}

console.log(foo);
{
console.log(foo);
function foo() {}
    foo = 1;
console.log(foo);
}
console.log(foo);

9.
https://www.yuque.com/caoxiaosong-iq5i9/vc73ek/ocr0td
14 18 18 5

let x = 5;
function fn(x) {
return function(y) {
console.log(y + (++x));
    }
}
let f = fn(6);
f(7);
fn(8)(9);
f(10);
console.log(x);

10.

const curring = function curring() {
//编写代码实现以下输出
};
let add = curring();
let res = add(1)(2)(3);
console.log(res); //->6
add = curring();
res = add(1, 2, 3)(4);
console.log(res); //->10
add = curring();
res = add(1)(2)(3)(4)(5);
console.log(res); //->15

11.

// 实现plus和minus,完成以下输出
let n = 10;
let m = n.plus(10).minus(5);
console.log(m);//=>15(10+10-5)
let n = 10;
let m = n.plus(10).minus(5);
console.log(m);//=>15(10+10-5)
Number.prototype.plus = function (num = 0) {
    return this + num;
};
Number.prototype.minus = function (num = 0) {
    return this - num;
};

12.
2 4 11 2 33

function Foo(){
    getName = function () {
console.log(1);
    };
return this;
}
Foo.getName = function () {
console.log(2);
};
Foo.prototype.getName = function () {
console.log(3);
};
var getName = function () {
console.log(4);
};
function getName() {
console.log(5);
}
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

13.

function Dog(name) {
this.name = name;
}
Dog.prototype.bark = function () {
console.log('wangwang');
}
Dog.prototype.sayName = function () {
console.log('my name is ' + this.name);
}
/*
let sanmao = new Dog('三毛');
sanmao.sayName();
sanmao.bark();
*/
function _new() {
//=>完成你的代码   
}
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=>"wangwang"
sanmao.sayName(); //=>"my name is 三毛"
console.log(sanmao instanceof Dog); //=>true

14.
{2: 1, 3: 2, length: 4, push: ƒ}

let obj = {
2: 3,
3: 4,
length: 2,
push: Array.prototype.push
}
obj.push(1);
obj.push(2);
console.log(obj);

15.

// 基于JS实现内置call
Function.prototype.call = function call(context, ...params) {
    // this->fn 要执行的函数   context->obj 要改变的THIS   params->[10,20] 要传递的实参
      // 必须保证context是个对象 原始值类型不能设置成员 执行的时候会报错
    if (context == null) context = window;//如果第一个参数不传或者NUll this默认更改为window
    let type = typeof context; //判断所属对象
    if (type !== "object" && type !== "function") {
        // 把传递的原始值类型变为对应的对象类型值
        context = Object(context);
    }
    let key = Symbol(),
        result;
    context[key] = this; //给context添加属性 但是不能随便加 万一context本身的属性名就是你写的 这样会被覆盖 所以用了唯一值
    result = context[key](...params);
    delete context[key]; // 用完记得把新加的属性删除掉
    return result;
};

16.

// 基于JS实现内置bind
Function.prototype.bind = function bind(context, ...params) {
};

17.

// 检测是否为纯粹的对象
const isPlainObject = function isPlainObject(obj) {
};

18.

// 实现数组和对象的深拷贝 
const deepClone = function deepClone(obj) {
};

19.
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
    resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');

20.
2 1 4 3

let body = document.body;
body.addEventListener('click', function () {
Promise.resolve().then(() => {
console.log(1);
    });
console.log(2);
});
body.addEventListener('click', function () {
Promise.resolve().then(() => {
console.log(3);
    });
console.log(4);
});

21.

console.log('start');
let intervalId;
Promise.resolve().then(() => {
console.log('p1');
}).then(() => {
console.log('p2');
});
setTimeout(() => {
Promise.resolve().then(() => {
console.log('p3');
    }).then(() => {
console.log('p4');
    });
    intervalId = setInterval(() => {
console.log('interval');
    }, 3000);
console.log('timeout1');
}, 0);

22.

//实现一个sleep函数的定义,让sleep的功能setTimeout类似,但是是promise风格的使用方式
function sleep(time){
// 具体实现代码
}
sleep(2000).then(function(){
console.log('logged after 2 seconds.');
});

简答题「每题5分」
1.谈谈对闭包的理解

从基础知识方面来讲
堆栈内存是一种机制概念, 函数执行会产生私有上下文,当上下文中的东西被外界占用了,当前上下文不能被释放,变量和值也就被保留了下来 
之前绑定事件的时候有块内容是用闭包的形式,自执行函数 发现性能不是很好 后来更改成了事件委托

2.谈谈你对面向对象的理解

  • 面向对象这种思想 就是让我们像认知自然界一样 去开发 设计 研究 使用 一门编程语言
    • 对象:泛指 万物皆对象
    • 类:对对象的具体细分
    • 实例:类中的具体事务/成员

例如:我们学习数组,我们先拿出数组类Array中的一个实例[也就是一个数组,我们看这个实例的特点和能使用的方法] 这样以后其他的数组也具备这个特点和对应的方法…

  • 每个实例和每个实例都是“单独的” 有自己的私有属性方法
  • 但是它们所属类赋予他们的公共的属性和方法
  • 真正具备”私有”和”公有”两种特点的,并且可以有效管理
    • image.png
      面向过程【POP】就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;
      面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
      面向对象【OOP】是以功能来划分问题,而不是步骤。面向对象使用对象,类,继承,封装等基本概念来进行程序设计 可扩展性强 解决了代码重用性
      
      3.简述浏览器渲染的步骤和如何减少DOM重排
      4..JS中数据类型检测有哪些办法,及各自优缺点

5.简述JS中的继承方案
6.简述什么是事件委托,及其作用

通过点击子级元素来触发父级元素的事件【因为事件的冒泡机制】
利用事件源e.target||e.srcElment来获取点击的元素
本来是要绑定给每一个子元素事件,我们可以绑定到父元素
通过事件的冒泡结合 e.target 实现了要的效果,避免了给每个一个元素绑定点击事件
每个元素绑定事件,多了话 利用给父元素绑定事件 比每个元素绑定事件性能高

7.简述mouseover和mouseenter的区别

over和out是忽略元素之间的层级关系,只看鼠标在哪个元素显示的范围上,存在事件冒泡

enter和leave会受到元素之间的层级关系,默认阻止了事件冒泡机制

8.简述从输入URL到看到页面的步骤
9.简述浏览器的缓存机制
10.简述GET和POST请求的区别、以及fetch和axios的区别
11.简述常见的跨域方案及实现原理
12.谈谈你做过的性能优化方案