1.css中link和@import的区别
区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS
区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
区别4:link支持使用Javascript控制DOM去改变样式;而@import不支持。
2.请根据优先级为选择器排序:id,class,tag,style,!important
!important > style > id > class > tag
3.请写一个正则表达式满足这样的规则:15到20位的大写字母或数字
/([A-Z]|[0-9]){15,20}/
4.双向数据绑定的实现原理
// Object.defineProperty 方式
var obj = {}
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function(){
return obj[key]
},
set: function(newVal){
obj[key] = newVal
}
})
// proxy方式
const obj = {};
const newObj = new Proxy(obj, {
get: function(target, key, receiver) {
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {
return Reflect.set(target, key, value, receiver);
},
})
5.下面的代码会输出什么结果?
var fullname ='a';
var obj = {
fullname: 'b',
prop:{
fullname: 'c',
getFullName:function(){
return this.fullname;
}
}
};
console.log(obj.prop.getFullName()); // =>c
var test = obj.prop.getFullName;
console.log(test()) // => a
6.以下代码输出的结果依次是
setTimeout(() => {
console.log(1)
}, 0)
new Promise(function exectutor(resolve) {
console.log(2)
for (var i = 0; i < 10000; i++) {
i == 9999 && resolve()
}
console.log(3)
}).then(function() {
console.log(4)
})
console.log(5)
// => 2,3,5,4,1
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
})
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},0)
// => Promise1,setTimeout1,Promise2,setTimeout2
console.log('start');
setTimeout(() => {
console.log('setTimeout');
}, 0)
new Promise((resolve, reject) =>{
for (var i = 0; i < 5; i++) {
console.log(i);
}
resolve(); // 修改promise实例对象的状态为成功的状态
}).then(() => {
console.log('promise实例成功回调执行');
})
console.log('end');
// => start,0,1,2,3,4,end,promise实例成功回调执行,setTimeout
7.请写一个函数对比两个版本号的大小,如 1.2.3 和 2.1.5
function que(param1,param2) {
var param1Arr = param1.split('.').join('')
var param2Arr = param2.split('.').join('')
return Number(param1Arr)>Number(param2Arr)
}
8.深拷贝方案有哪些,手写一个深拷贝
// 1.JSON.parse(JSON.stringify())
// 2.手写递归方法
//定义检测数据类型的功能函数
function checkedType(target) {
return Object.prototype.toString.call(target).slice(8, -1)
}
//实现深度克隆---对象/数组
function clone(target) {
//判断拷贝的数据类型
//初始化变量result 成为最终克隆的数据
let result, targetType = checkedType(target)
if (targetType === 'Object') {
result = {}
} else if (targetType === 'Array') {
result = []
} else {
return target
}
//遍历目标数据
for (let i in target) {
//获取遍历数据结构的每一项值。
let value = target[i]
//判断目标结构里的每一值是否存在对象/数组
if (checkedType(value) === 'Object' ||
checkedType(value) === 'Array') { //对象/数组里嵌套了对象/数组
//继续遍历获取到value值
result[i] = clone(value)
} else { //获取到value值是基本的数据类型或者是函数。
result[i] = value;
}
}
return result
}
// 3.函数库lodash 该函数库也有提供_.cloneDeep用来做 Deep Copy
var _ = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f); // false
9.请尽量简单的实现一个发布订阅模式,要求满足:发布、订阅、移除
const Event = {
clientList: {},
// 绑定事件监听
listen(key, fn){
if(!this.clientList[key]){
this.clientList[key] = [];
}
this.clientList[key].push(fn);
return true;
},
// 触发对应事件
trigger(){
const key = Array.prototype.shift.apply(arguments),
fns = this.clientList[key];
if(!fns || fns.length === 0){
return false;
}
for(let fn of fns){
fn.apply(null, arguments);
}
return true;
},
// 移除相关事件
remove(key, fn){
let fns = this.clientList[key];
// 如果之前没有绑定事件
// 或者没有指明要移除的事件
// 直接返回
if(!fns || !fn){
return false;
}
// 反向遍历移除置指定事件函数
for(let l = fns.length - 1; l >= 0; l--){
let _fn = fns[l];
if(_fn === fn){
fns.splice(l, 1);
}
}
return true;
}
}
// 为对象动态安装 发布-订阅 功能
const installEvent = (obj) => {
for(let key in Event){
obj[key] = Event[key];
}
}
let salesOffices = {};
installEvent(salesOffices);
// 绑定自定义事件和回调函数
salesOffices.listen("event01", fn1 = (price) => {
console.log("Price is", price, "at event01");
})
salesOffices.listen("event02", fn2 = (price) => {
console.log("Price is", price, "at event02");
})
salesOffices.trigger("event01", 1000);
salesOffices.trigger("event02", 2000);
salesOffices.remove("event01", fn1);
// 输出: false
// 说明删除成功
console.log(salesOffices.trigger("event01", 1000));
扫一扫,关注我吧