this指向题目
let length = 10;
function fn() {
return this
}
var obj1 = {
length: 5,
test1: function () {
return fn();
},
test3: function () {
return this
},
test4: function () {
setTimeout(function () {
console.log(this)
}, 500)
},
test5() {
return {
fn: () => {
return this
}
}
},
test6() {
setTimeout(() => {
console.log(this)
}, 500)
}
};
obj1.test2 = fn;
var obj2 = {
length: 99
}
console.log(obj1.test1.call());//window
console.log(obj1.test1());//window
console.log(obj1.test2.call());//window
console.log(obj1.test2());//obj1
console.log(obj1.test4());//undefined
console.log(obj1.test5().fn());//obj1
console.log(obj1.test6());//undefined
//题2
var s1 = {
lll:'s1',
t1: function(){ // 测试this指向调用者
return this
},
t2: () => { // 测试箭头函数,this并未指向调用者
return this
},
t3: { // 测试对象中的对象
tt1: function() {
return this
}
},
t4: { // 测试箭头函数以及非函数调用this并未指向调用者
tt1: () => {
return this
}
},
t5: function(){ // 测试函数调用时箭头函数的this的指向,其指向了上一层对象的调用者
return {
tt1: () => {
return this
}
}
},
t6: function(){
return {
tt2: nnn
}
},
t7: function(){
return nnn
}
}
function nnn(){
return this
}
// const nnn = () => {
// return this
// }
console.log(s1.t1()); // s1对象 // 此处的调用者为 s1 所以打印对象为 s1
console.log(s1.t2()); // Window
console.log(s1.t3.tt1()); // s1.t3对象
console.log(s1.t4.tt1()); // Window
console.log(s1.t5().tt1()); // s1对象
console.log(s1.t6().tt2())//{tt2: ƒ}
console.log(s1.t7()())//window
复制代码
手写reduce
function reduceFn(a, f, init) {
var i = 0,
len = a.length,
val;
if (arguments.length > 2) {
val = init;
} else {
while (i < len) {
if (i in a) {
val = a[i++];
break;
} else {
i++;
}
}
}
while (i < len) {
if (i in a) val = f.call(undefined, val, a[i], i, a);
i++;
}
return val;
}
复制代码
手写eventBus
class eventBus {
constructor(){
this._event = this._event || new Object;
}
}
eventBus.prototype.emit = function(type,...args){
let e = this._event[type];
console.log(e)
if(Array.isArray(e)){
for(let i=0;i<e.length;i++){
e[i].call(this,...args)
}
}else{
e.call(this,...args)
}
}
eventBus.prototype.addListener = function(type,fn){
e = this._event[type];
if(e){
this._event[type] = [...e,fn]
}else{
this._event[type] = [fn]
}
}
let eventEmit = new eventBus()
eventEmit.addListener('arson', man => {
console.log(`expel ${man}`);
});
eventEmit.addListener('arson', man => {
console.log(`save ${man}`);
});
eventEmit.addListener('arson', man => {
console.log(`kill ${man}`);
});
触发事件
eventEmit.emit('arson','test')
复制代码
手写call、apply、bind
Function.prototype._call = function (base, ...args) {
base = base || window;
base.fn = this;
var result = base.fn(...args);
delete base.fn;
return result;
};
Function.prototype._apply = function (base, args) {
base = base || window;
base.fn = this;
var result = base.fn(...args);
delete base.fn;
return result;
};
Function.prototype._bind = function (base, ...args1) {
base = base || window;
base.fn = this;
return function (args2) {
var result = base.fn(...args1, args2);
delete base.fn;
return result;
};
};
复制代码
手写new
function _new(base, ...args) {
let obj = {};
obj.__proto__ = base.prototype;
let res = base.apply(obj, args);
return typeof base === "object" ? res : obj;
}
复制代码
简单深拷贝
function deepClone(list){
if(list === null){
return null
}
let arr = Array.isArray(list) ? [] : {};
for(let i in list){
if(list[i] && typeof list[i] === 'object'){
arr[i] = deepClone(list[i])
}else{
arr[i] = list[i]
}
}
return arr
}
复制代码
sleep
const sleep = (time) => {
return new Promise((resolve) => {
setTimeout(() => resolve(), time);
});
};
sleep(1000).then(() => {
console.log("sleep");
});
复制代码
手写promise相关
function _Promise(executor) {
this.status = "pedding";
this.value = null;
this.reason = null;
const resolve = (value) => {
this.value = value;
this.status = "resolved";
};
const reject = (reason) => {
this.reason = reason;
this.status = "rejected";
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
_Promise.prototype.then = function (resolve, reject) {
setTimeout(() => {
if (this.status === "resolved") {
resolve(this.value);
} else {
reject(this.reason);
}
}, 0);
};
//promise.all
_Promise.prototype.all = function (arr) {
return new Promise((resolve, reject) => {
let count = 0,
final = [];
arr.forEach((ele, i) => {
Promise.resolve(ele).then(
(result) => {
final[i] = result;
if (++count === arr.length) {
resolve(final);
}
},
(reason) => {
reject(reson);
}
);
});
});
};
复制代码
常见排序
function sortFn(arr){//冒泡
for(let i=0;i<arr.length-1;i++){
for(let j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
let temp = arr[j];
arr[j] = arr[j+1]
arr[j+1] = temp
}
}
}
return arr
}
function sortFn(arr){//选择
for(let i=0;i<arr.length-1;i++){
let min = i;
for(let j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
min = j
}
}
if(min !== i){
let temp = arr[i]
arr[i] = arr[min]
arr[min] = temp
}
}
return arr
}
function sortFn(arr){//插入
for(let i=1;i<arr.length;i++){
let j = i
while(j>0&&arr[j-1]>arr[j]){
let temp = arr[j-1]
arr[j-1] = arr[j]
arr[j] = temp
j--
}
}
return arr
}
function sortFn(arr) {
//希尔排序
let gap = Math.floor(arr.length / 2);
while(gap>0){
for(let i=gap;i<arr.length;i++){
let j = i,temp = arr[j];
while(j-gap>-1 && arr[j-gap] > temp){
arr[j] = arr[j-gap]
j = j - gap
}
arr[j] = temp
}
gap = Math.floor(gap / 2);
}
return arr;
}
function quickSort (arr) {//快排
if (arr.length <= 1) return arr
var arr1 = [], arr2 = []
for (var i = 1; i < arr.length; i++) {
if (arr[i] < arr[0]) {
arr1.push(arr[i])
} else {
arr2.push(arr[i])
}
}
arr1 = quickSort(arr1)
arr2 = quickSort(arr2)
arr1.push(arr[0])
return arr1.concat(arr2)
}
function quickSort(arr,left,right){//快排优化版(首先排好左边)
left = left || 0;
right = right || arr.length-1;
if(left<right){
let index = getIndex(arr,left,right)//获取中间
quickSort(arr,left,index-1)
quickSort(arr,index+1,right)
}
return arr
}
function getIndex(arr,left,right){
let index = left + 1;
for(let i=index;i<=right;i++){
if(arr[i]<arr[left]){
swap(arr,index,i)
index++
}
}
swap(arr,left,index-1)
return index-1
}
function swap(arr,index,i){
let temp = arr[index]
arr[index] = arr[i]
arr[i] = temp
}
console.log(quickSort([1,3,99,2,66]))
复制代码
哈希路由原理
function Router() {
this.routes = Object.create(null);
this.view = null
}
Router.prototype.init = function (view) {
this.view = view;
this.refresh()
window.addEventListener('hashchange', this.refresh.bind(this), false)
}
Router.prototype.refresh = function () {
let path = window.location.hash, fn = this.routes[path];
if (fn) {
this.view.innerHTML = fn()
}
console.log(this.view, this.routes)
}
Router.prototype.route = function (path, callback) {
this.routes[path] = () => this.view.innerHTML = callback() || '';
}
var testRoute = new Router();
testRoute.init(document.getElementById('root'))
testRoute.route('#/blue', function () {
return '#/blue'
})
testRoute.route('#/green', function () {
return '#/green'
})
复制代码
手写map
function myMap(arr,fn,base){
base = base || undefined
let res=[]
for(let i=0;i<arr.length;i++){
res[i] = fn.call(base,arr[i],i)
}
return res
}
console.log(myMap([2,3,1,22],(item,...rest)=>{return item}))
复制代码
其他
function Foo() {
Foo.a = function () {
console.log(1);
};
this.a = function () {
console.log(2,343434);
};
}
Foo.prototype.a = function () {
console.log(4);
};
Foo.a = 3;
var foo = new Foo()
console.log(foo.a,Foo.a);
foo.a()
复制代码
- 内联样式,如: style="...",权值为
1000
。 - ID选择器,如:#content,权值为
0100
。 - 类,伪类、属性选择器,如.content,权值为
0010
。 - 类型选择器、伪元素选择器,如div p ::after,权值为
0001
。 - 通配符、子选择器、相邻选择器等。如
* > +
,权值为0000
。 - 继承的样式没有权值
css3
为了区分两者,已经明确规定了伪类用一个冒号来表示,而伪元素则用两个冒号来表示
formData类型参数不需要设置contentType