5-2020-快手-前端

1.自我介绍。在项目里的角色。有遇到过什么困难吗?为什么选择前端。

2.登陆实现的原理。

3.了解浏览器渲染的不兼容吗?元素的样式不兼容。

不同浏览器的标签默认的margin和padding不同:使用Normalize来清除默认样式

块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大:在float的标签样式控制中加入 display:inline;将其转化为行内属性

4.CSS中class的优先级

css层叠规则:——《CSS权威指南》第三章 结构与层叠

  1. 显式权重:分为 !important, 来源两方面: !important读者样式 > !important创作人员样式 > 创作人员样式 > 读者样式 > 用户代理样式
  2. 特殊性:内联样式(1,0,0,0)> ID选择器(0,1,0,0) > 类选择器,属性选择器,伪类选择器(0,0,1,0) > 元素选择器,伪元素选择器(0,0,0,1) > 通配选择器(0,0,0,0)> 继承(null)
  3. 出现顺序:一个声明在样式表或文档中越后出现,他的权重就越大
 .a{
  color:red;
}
 
.b{
  color:green;
}

 <div class="a b"> 		
      ab
  </div>
  <div class="b a">
      ba 
  </div>

结果是什么颜色:两个都是绿色。因为:class的优先级与在元素中的指定顺序无关,和class的定义顺序有关,最后定义的优先级最高。

多类选择器: ——《CSS权威指南》第二章 选择器

  <div class="a"> 
      a
  </div>
  <div class="b">
      b 
  </div>
  <div class="a b">
      ab 
  </div>

 
.a.b{
  color:brown;
}
.a{
  color:red;
}
.b{
  color:green;
}
 

5.函数变量提升+闭包

var count = 10;

function a(){
    console.log(count+10);
}

function b(){
    var count = 20;
    return a(count)
}
b();

6.原型+原型链+构造

function foo(){
    this.a = 1;
    return{
        a:4,
        b:5}
}

let Foo = new foo();

Foo.prototype.a = 6;
Foo.prototype.b = 7;
Foo.prototype.c = 8;

console.log(Foo.prototype.a);
console.log(Foo.prototype.b);
console.log(Foo.prototype.c);

new操作符具体做了什么,用代码解释:

var Foo = new foo();

该步一共做了三件事:即 var Foo = {}; //创建了一个空对象obj

Foo.__proto__ = foo.prototype; //将这个空对象的__proto__成员指向了foo函数对象prototype成员对象

foo.call(obj);//将Base函数对象的this指针替换成obj。

7.nodeJS异步+事件循环

setTimeout(function(){
    console.log(2);
},0);

new Promise(function(resolve){
    console.log(3);
    process.nextTick(resolve());
}).then(function(){
    console.log(5);
});

process.nextTick(function(){
    console.log(7);
});

setImmediate(function(){
    console.log(1);
},0);

输出:3 7 5 2 1

思路参考https://blog.csdn.net/weixin_45440502/article/details/109729016  7.判断nodejs异步输出顺序

8.斐波拉奇:f(0)=0,f(1)=1

暴力(递归):

var fib = function(n) {
    if (n<=0) return 0
    if (n == 1) return 1
    return fib(n-1)+fib(n-2)
}

记忆(循环):

var fib = function(n) {
    if (n<=0) return 0
    if (n == 1) return 1
    let arr = [0,1];
    let i =2;
    for(;i<=n;i++){
        arr[i] = arr[i-1]+arr[i-2]
    }
    return arr[i-1]
}

9.'get-element-by-id' 用驼峰法转化为 'getElementById'

 数组:

   用到字符串两个方法:charAt()和substr()。其他方法见我另一篇文章https://blog.csdn.net/weixin_45440502/article/details/109729016 第11点。

function combo(msg){
var arr=msg.split("-");
var i=1;
for(;i<arr.length;i++){
arr[i]=arr[i].charAt(0).toUpperCase() + arr[i].substr(1,arr[i].length-1);
}
console.log(arr);//['get','Element','By','Id']
msg=arr.join("");
console.log(msg)//getElementById
}
combo("get-element-by-id");

或:用数组的方法:map()和slice()。数组其他方法见我另一篇文章 https://blog.csdn.net/weixin_45440502/article/details/109646845 第13点。

function getCamelCase( str ) {
    var arr = str.split( '-' );
    return arr.map( function( item, index ) {
        if( index === 0 ){
            return item;
        }else{
            return item.charAt(0).toUpperCase() + item.slice( 1 );
        }
    }).join('');
}
console.log( getCamelCase( 'get-element-by-id' ) ); //getElementById

我当时写的方法:用到Array.from(arr)

function combo(msg){
var arr=msg.split("-");
var i=1;
let temp,newarr;
for(;i<arr.length;i++){
  newarr = Array.from(arr[i]);//这里很重要,我当时写错了,写的是arr[i].from()
  newarr[0] = newarr[0].toUpperCase()
  arr[i] = newarr.join('')
}
console.log(arr);//['get','Element','By','Id']
msg=arr.join("");
console.log(msg)//getElementById
}
combo("get-element-by-id");

 正则:

function getCamelCase( str ) {
    return str.replace( /-([a-z])/g, function( all, i ){
        return i.toUpperCase();
    } )
}
console.log( getCamelCase( 'get-element-by-id' ) ); //getElementById

10.解释promise.all的作用,并写出原理

1、作用

  • 入参是一个数组,可以传基本类型值,也可以传promise对象。
  • 返回结果是一个Promise对象。
  • 入参数组中的每一个都返回成功,才返回成功。
  • 只要有一个执行失败,则返回失败。

2.适用场景

  • 适合多个异步调用函数,并且多个异步函数的调用的入参和结果都无必然联系,比如多个文件的上传或下载。
  • 多个异步函数的执行只关注成功或失败结果。

3.原理代码

Promise.all = function(values){
    return new Promise((resolve,reject)=>{
        let results = []; // 结果数组
        let i = 0;
        let processData = (value,index)=>{
            results[index] = value;
            // 当成功的个数 和 当前的参数个数相等就把结果抛出去
            if(++i === values.length){
                resolve(results);
            }
        }
        for(let i = 0 ; i< values.length;i++){
            let current = values[i]; // 拿到数组中每一项
            // 判断是不是一个promise
            if((typeof current === 'object' &&  current !==null)|| typeof current == 'function'){
                // 如果是promise
                if(typeof current.then == 'function'){
                    // 就调用这个promise的then方法,把结果和索引对应上,如果任何一个失败了返回的proimise就是一个失败的promise
                    current.then(y=>{
                        processData(y,i);
                    },reject)
                }else{
                    processData(current,i);
                }
            }else{
                processData(current,i);
            }
        }
    });
}

// 封装 Promise.all方法
Promise.all = function (values) {
    return new Promise((resolve, reject) => {
        let result = []; // 存放返回值
        let counter = 0; // 计数器,用于判断异步完成
        function processData(key, value) {
            result[key] = value;
            // 每成功一次计数器就会加1,直到所有都成功的时候会与values长度一致,则认定为都成功了,所以能避免异步问题
            if (++counter === values.length) {
                resolve(result);
            }
        }
        // 遍历 数组中的每一项,判断传入的是否是promise
        for (let i = 0; i < values.length; i++) {
            let current = values[i];
            // 如果是promise则调用获取data值,然后再处理data
            if (isPromise(current)) {
                current.then(data => {
                    processData(i, data);
                }, reject);
            } else {
                // 如果不是promise,传入的是普通值,则直接返回
                processData(i, current);
            }
        }
    });
}

4.代码解析

  • Promise.all是挂载到Promise类实例上
  • 返回的是一个Promise
  • 需要遍历入参数组中的每一项,判断传入的是不是promise,如果是promise则执行then方法,然后将then方法中的成功回调的data返回,失败则reject
  • 如果入参数组中有基本数值,则直接返回
  • 通过计数器,来判断函数的执行结果

手写promise

源码:

// 上源码
;(function (global) {
	global.Promise = Promise
	// 定义promise三种状态
	const PENDING = 'pending'
	const FULFILLED = 'fulfilled'
	const REJECTED = 'rejected'

	function Promise(fn) {
		this.state = PENDING
		this.fulfilledQueue = []
		this.rejectedQueue = []
		try {
			fn(
				// 此处需注意this指向
				(res) => {
					this._resolve(res)
				},
				(err) => {
					this._reject(err)
				}
				// 或者this.resolve.bind(this), this.reject.bind(this))
			)
		} catch (e) {
			reject(e)
		}
	}

	Promise.prototype = {
		constructor: Promise,
		_resolve: function (value) {
			if (value instanceof Promise) {
				return value.then(
					// 此处需注意this指向
					(res) => {
						this._resolve(res)
					},
					(err) => {
						this._reject(err)
					}
				)
			}
			setTimeout(() => {
				if (this.state === PENDING) {
					this.state = FULFILLED
					this.value = value
					this.fulfilledQueue.forEach((fn) => fn(this.value))
				}
			})
		},
		_reject: function (value) {
			setTimeout(() => {
				if (this.state === PENDING) {
					this.state = REJECTED
					this.value = value
					this.rejectedQueue.forEach((fn) => fn(this.value))
				}
			})
		},
		then: function (fulfilled, rejected) {
			this.fulfilled =
				typeof fulfilled === 'function' ? fulfilled : (v) => v
			this.rejected =
				typeof rejected === 'function'
					? rejected
					: (err) => {
							throw err
					  }
			if (this.state === PENDING) {
				return new Promise((resolve, reject) => {
					this.fulfilledQueue.push(() => {
						try {
							this.value = this.fulfilled(this.value)
							resolve(this.value)
						} catch (error) {
							reject(error)
						}
					})
					this.rejectedQueue.push(() => {
						try {
							this.value = this.rejected(this.value)
							resolve(this.value)
						} catch (error) {
							reject(error)
						}
					})
				})
			}
			if (this.state === FULFILLED) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						try {
							this.value = this.fulfilled(this.value)
							resolve(this.value)
						} catch (error) {
							reject(error)
						}
					})
				})
			}
			if (this.state === REJECTED) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						try {
							this.value = this.rejected(this.value)
							resolve(this.value)
						} catch (error) {
							reject(error)
						}
					})
				})
			}
		},
	}
})(window)


 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值