当前位置: 首页 > news >正文

晋江哪里可以学建设网站seo下载站

晋江哪里可以学建设网站,seo下载站,佛山商业网站建设,网页设计入门书籍实现call方法 call做了什么: 将函数设为对象的属性执行和删除这个函数指定this到函数并传入给定参数执行函数如果不传入参数,默认指向为 window // 模拟 call bar.mycall(null); //实现一个call方法: // 原理:利用 context.xxx self obj.…

实现call方法

call做了什么:

  • 将函数设为对象的属性
  • 执行和删除这个函数
  • 指定this到函数并传入给定参数执行函数
  • 如果不传入参数,默认指向为 window
// 模拟 call bar.mycall(null);
//实现一个call方法:
// 原理:利用 context.xxx = self obj.xx = func-->obj.xx()
Function.prototype.myCall = function(context = window, ...args) {if (typeof this !== "function") {throw new Error('type error')}// this-->func  context--> obj  args--> 传递过来的参数// 在context上加一个唯一值不影响context上的属性let key = Symbol('key')context[key] = this; // context为调用的上下文,this此处为函数,将这个函数作为context的方法// let args = [...arguments].slice(1)   //第一个参数为obj所以删除,伪数组转为数组// 绑定参数 并执行函数let result = context[key](...args);// 清除定义的this 不删除会导致context属性越来越多delete context[key];// 返回结果 return result;
};
//用法:f.call(obj,arg1)
function f(a,b){console.log(a+b)console.log(this.name)
}
let obj={name:1
}
f.myCall(obj,1,2) //否则this指向window

实现双向数据绑定

let obj = {}
let input = document.getElementById('input')
let span = document.getElementById('span')
// 数据劫持
Object.defineProperty(obj, 'text', {configurable: true,enumerable: true,get() {console.log('获取数据了')},set(newVal) {console.log('数据更新了')input.value = newValspan.innerHTML = newVal}
})
// 输入监听
input.addEventListener('keyup', function(e) {obj.text = e.target.value
})

实现数组的flat方法

function _flat(arr, depth) {if(!Array.isArray(arr) || depth <= 0) {return arr;}return arr.reduce((prev, cur) => {if (Array.isArray(cur)) {return prev.concat(_flat(cur, depth - 1))} else {return prev.concat(cur);}}, []);
}

手写 Object.create

思路:将传入的对象作为原型

function create(obj) {function F() {}F.prototype = objreturn new F()
}

模拟Object.create

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

// 模拟 Object.createfunction create(proto) {function F() {}F.prototype = proto;return new F();
}

交换a,b的值,不能用临时变量

巧妙的利用两个数的和、差:

a = a + b
b = a - b
a = a - b

参考 前端进阶面试题详细解答

实现数组的map方法

Array.prototype._map = function(fn) {if (typeof fn !== "function") {throw Error('参数必须是一个函数');}const res = [];for (let i = 0, len = this.length; i < len; i++) {res.push(fn(this[i]));}return res;
}

实现instanceOf

// 模拟 instanceof
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式var O = R.prototype; // 取 R 的显示原型L = L.__proto__; // 取 L 的隐式原型while (true) {if (L === null) return false;if (O === L)// 这里重点:当 O 严格等于 L 时,返回 truereturn true;L = L.__proto__;}
}

实现数组去重

给定某无序数组,要求去除数组中的重复数字并且返回新的无重复数组。

ES6方法(使用数据结构集合):

const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];Array.from(new Set(array)); // [1, 2, 3, 5, 9, 8]

ES5方法:使用map存储不重复的数字

const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];uniqueArray(array); // [1, 2, 3, 5, 9, 8]function uniqueArray(array) {let map = {};let res = [];for(var i = 0; i < array.length; i++) {if(!map.hasOwnProperty([array[i]])) {map[array[i]] = 1;res.push(array[i]);}}return res;
}

手写节流函数

函数节流是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。

// 函数节流的实现;
function throttle(fn, delay) {let curTime = Date.now();return function() {let context = this,args = arguments,nowTime = Date.now();// 如果两次时间间隔超过了指定时间,则执行函数。if (nowTime - curTime >= delay) {curTime = Date.now();return fn.apply(context, args);}};
}

实现Event(event bus)

event bus既是node中各个模块的基石,又是前端组件通信的依赖手段之一,同时涉及了订阅-发布设计模式,是非常重要的基础。

简单版:

class EventEmeitter {constructor() {this._events = this._events || new Map(); // 储存事件/回调键值对this._maxListeners = this._maxListeners || 10; // 设立监听上限}
}// 触发名为type的事件
EventEmeitter.prototype.emit = function(type, ...args) {let handler;// 从储存事件键值对的this._events中获取对应事件回调函数handler = this._events.get(type);if (args.length > 0) {handler.apply(this, args);} else {handler.call(this);}return true;
};// 监听名为type的事件
EventEmeitter.prototype.addListener = function(type, fn) {// 将type事件以及对应的fn函数放入this._events中储存if (!this._events.get(type)) {this._events.set(type, fn);}
};

面试版:

class EventEmeitter {constructor() {this._events = this._events || new Map(); // 储存事件/回调键值对this._maxListeners = this._maxListeners || 10; // 设立监听上限}
}// 触发名为type的事件
EventEmeitter.prototype.emit = function(type, ...args) {let handler;// 从储存事件键值对的this._events中获取对应事件回调函数handler = this._events.get(type);if (args.length > 0) {handler.apply(this, args);} else {handler.call(this);}return true;
};// 监听名为type的事件
EventEmeitter.prototype.addListener = function(type, fn) {// 将type事件以及对应的fn函数放入this._events中储存if (!this._events.get(type)) {this._events.set(type, fn);}
};// 触发名为type的事件
EventEmeitter.prototype.emit = function(type, ...args) {let handler;handler = this._events.get(type);if (Array.isArray(handler)) {// 如果是一个数组说明有多个监听者,需要依次此触发里面的函数for (let i = 0; i < handler.length; i++) {if (args.length > 0) {handler[i].apply(this, args);} else {handler[i].call(this);}}} else {// 单个函数的情况我们直接触发即可if (args.length > 0) {handler.apply(this, args);} else {handler.call(this);}}return true;
};// 监听名为type的事件
EventEmeitter.prototype.addListener = function(type, fn) {const handler = this._events.get(type); // 获取对应事件名称的函数清单if (!handler) {this._events.set(type, fn);} else if (handler && typeof handler === "function") {// 如果handler是函数说明只有一个监听者this._events.set(type, [handler, fn]); // 多个监听者我们需要用数组储存} else {handler.push(fn); // 已经有多个监听者,那么直接往数组里push函数即可}
};EventEmeitter.prototype.removeListener = function(type, fn) {const handler = this._events.get(type); // 获取对应事件名称的函数清单// 如果是函数,说明只被监听了一次if (handler && typeof handler === "function") {this._events.delete(type, fn);} else {let postion;// 如果handler是数组,说明被监听多次要找到对应的函数for (let i = 0; i < handler.length; i++) {if (handler[i] === fn) {postion = i;} else {postion = -1;}}// 如果找到匹配的函数,从数组中清除if (postion !== -1) {// 找到数组对应的位置,直接清除此回调handler.splice(postion, 1);// 如果清除后只有一个函数,那么取消数组,以函数形式保存if (handler.length === 1) {this._events.set(type, handler[0]);}} else {return this;}}
};

实现具体过程和思路见实现event

手写 call 函数

call 函数的实现步骤:

  1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。
  2. 判断传入上下文对象是否存在,如果不存在,则设置为 window 。
  3. 处理传入的参数,截取第一个参数后的所有参数。
  4. 将函数作为上下文对象的一个属性。
  5. 使用上下文对象来调用这个方法,并保存返回结果。
  6. 删除刚才新增的属性。
  7. 返回结果。
// call函数实现
Function.prototype.myCall = function(context) {// 判断调用对象if (typeof this !== "function") {console.error("type error");}// 获取参数let args = [...arguments].slice(1),result = null;// 判断 context 是否传入,如果未传入则设置为 windowcontext = context || window;// 将调用函数设为对象的方法context.fn = this;// 调用函数result = context.fn(...args);// 将属性删除delete context.fn;return result;
};

实现非负大整数相加

JavaScript对数值有范围的限制,限制如下:

Number.MAX_VALUE // 1.7976931348623157e+308
Number.MAX_SAFE_INTEGER // 9007199254740991
Number.MIN_VALUE // 5e-324
Number.MIN_SAFE_INTEGER // -9007199254740991

如果想要对一个超大的整数(> Number.MAX_SAFE_INTEGER)进行加法运算,但是又想输出一般形式,那么使用 + 是无法达到的,一旦数字超过 Number.MAX_SAFE_INTEGER 数字会被立即转换为科学计数法,并且数字精度相比以前将会有误差。

实现一个算法进行大数的相加:

function sumBigNumber(a, b) {let res = '';let temp = 0;a = a.split('');b = b.split('');while (a.length || b.length || temp) {temp += ~~a.pop() + ~~b.pop();res = (temp % 10) + res;temp  = temp > 9}return res.replace(/^0+/, '');
}

其主要的思路如下:

  • 首先用字符串的方式来保存大数,这样数字在数学表示上就不会发生变化
  • 初始化res,temp来保存中间的计算结果,并将两个字符串转化为数组,以便进行每一位的加法运算
  • 将两个数组的对应的位进行相加,两个数相加的结果可能大于10,所以可能要仅为,对10进行取余操作,将结果保存在当前位
  • 判断当前位是否大于9,也就是是否会进位,若是则将temp赋值为true,因为在加法运算中,true会自动隐式转化为1,以便于下一次相加
  • 重复上述操作,直至计算结束

实现 add(1)(2)(3)

函数柯里化概念: 柯里化(Currying)是把接受多个参数的函数转变为接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术。

1)粗暴版

function add (a) {
return function (b) {return function (c) {return a + b + c;}
}
}
console.log(add(1)(2)(3)); // 6

2)柯里化解决方案

  • 参数长度固定
var add = function (m) {var temp = function (n) {return add(m + n);}temp.toString = function () {return m;}return temp;
};
console.log(add(3)(4)(5)); // 12
console.log(add(3)(6)(9)(25)); // 43

对于add(3)(4)(5),其执行过程如下:

  1. 先执行add(3),此时m=3,并且返回temp函数;

  2. 执行temp(4),这个函数内执行add(m+n),n是此次传进来的数值4,m值还是上一步中的3,所以add(m+n)=add(3+4)=add(7),此时m=7,并且返回temp函数

  3. 执行temp(5),这个函数内执行add(m+n),n是此次传进来的数值5,m值还是上一步中的7,所以add(m+n)=add(7+5)=add(12),此时m=12,并且返回temp函数

  4. 由于后面没有传入参数,等于返回的temp函数不被执行而是打印,了解JS的朋友都知道对象的toString是修改对象转换字符串的方法,因此代码中temp函数的toString函数return m值,而m值是最后一步执行函数时的值m=12,所以返回值是12。

  • 参数长度不固定
function add (...args) {//求和return args.reduce((a, b) => a + b)
}
function currying (fn) {let args = []return function temp (...newArgs) {if (newArgs.length) {args = [...args,...newArgs]return temp} else {let val = fn.apply(this, args)args = [] //保证再次调用时清空return val}}
}
let addCurry = currying(add)
console.log(addCurry(1)(2)(3)(4, 5)())  //15
console.log(addCurry(1)(2)(3, 4, 5)())  //15
console.log(addCurry(1)(2, 3, 4, 5)())  //15

实现日期格式化函数

输入:

dateFormat(new Date('2020-12-01'), 'yyyy/MM/dd') // 2020/12/01
dateFormat(new Date('2020-04-01'), 'yyyy/MM/dd') // 2020/04/01
dateFormat(new Date('2020-04-01'), 'yyyy年MM月dd日') // 2020年04月01日
const dateFormat = (dateInput, format)=>{var day = dateInput.getDate() var month = dateInput.getMonth() + 1  var year = dateInput.getFullYear()   format = format.replace(/yyyy/, year)format = format.replace(/MM/,month)format = format.replace(/dd/,day)return format
}

字符串查找

请使用最基本的遍历来实现判断字符串 a 是否被包含在字符串 b 中,并返回第一次出现的位置(找不到返回 -1)。

a='34';b='1234567'; // 返回 2
a='35';b='1234567'; // 返回 -1
a='355';b='12354355'; // 返回 5
isContain(a,b);
function isContain(a, b) {for (let i in b) {if (a[0] === b[i]) {let tmp = true;for (let j in a) {if (a[j] !== b[~~i + ~~j]) {tmp = false;}}if (tmp) {return i;}}}return -1;
}

Function.prototype.call

call唯一不同的是,call()方法接受的是一个参数列表

Function.prototype.call = function(context = window, ...args) {if (typeof this !== 'function') {throw new TypeError('Type Error');}const fn = Symbol('fn');context[fn] = this;const res = context[fn](...args);delete context[fn];return res;
}

模板引擎实现

let template = '我是{{name}},年龄{{age}},性别{{sex}}';
let data = {name: '姓名',age: 18
}
render(template, data); // 我是姓名,年龄18,性别undefined
function render(template, data) {const reg = /\{\{(\w+)\}\}/; // 模板字符串正则if (reg.test(template)) { // 判断模板里是否有模板字符串const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段template = template.replace(reg, data[name]); // 将第一个模板字符串渲染return render(template, data); // 递归的渲染并返回渲染后的结构}return template; // 如果模板没有模板字符串直接返回
}

封装异步的fetch,使用async await方式来使用

(async () => {class HttpRequestUtil {async get(url) {const res = await fetch(url);const data = await res.json();return data;}async post(url, data) {const res = await fetch(url, {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(data)});const result = await res.json();return result;}async put(url, data) {const res = await fetch(url, {method: 'PUT',headers: {'Content-Type': 'application/json'},data: JSON.stringify(data)});const result = await res.json();return result;}async delete(url, data) {const res = await fetch(url, {method: 'DELETE',headers: {'Content-Type': 'application/json'},data: JSON.stringify(data)});const result = await res.json();return result;}}const httpRequestUtil = new HttpRequestUtil();const res = await httpRequestUtil.get('http://golderbrother.cn/');console.log(res);
})();

AJAX

const getJSON = function(url) {return new Promise((resolve, reject) => {const xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Mscrosoft.XMLHttp');xhr.open('GET', url, false);xhr.setRequestHeader('Accept', 'application/json');xhr.onreadystatechange = function() {if (xhr.readyState !== 4) return;if (xhr.status === 200 || xhr.status === 304) {resolve(xhr.responseText);} else {reject(new Error(xhr.responseText));}}xhr.send();})
}

文章转载自:
http://restock.jtrb.cn
http://autonomous.jtrb.cn
http://malacostracous.jtrb.cn
http://brightness.jtrb.cn
http://hemiglobin.jtrb.cn
http://formalistic.jtrb.cn
http://conceited.jtrb.cn
http://radioconductor.jtrb.cn
http://luxation.jtrb.cn
http://phonomania.jtrb.cn
http://philosophaster.jtrb.cn
http://dakoit.jtrb.cn
http://fatheaded.jtrb.cn
http://expatriation.jtrb.cn
http://hodgepodge.jtrb.cn
http://totalitarianize.jtrb.cn
http://forward.jtrb.cn
http://aldermaston.jtrb.cn
http://micrometeoroid.jtrb.cn
http://sorrow.jtrb.cn
http://provencal.jtrb.cn
http://catholically.jtrb.cn
http://trephination.jtrb.cn
http://allometry.jtrb.cn
http://arrears.jtrb.cn
http://unspell.jtrb.cn
http://subsequently.jtrb.cn
http://wanderer.jtrb.cn
http://excreta.jtrb.cn
http://foxed.jtrb.cn
http://penthrite.jtrb.cn
http://dotard.jtrb.cn
http://matrilineal.jtrb.cn
http://owes.jtrb.cn
http://polyhidrosis.jtrb.cn
http://thereunto.jtrb.cn
http://housefather.jtrb.cn
http://mesothelial.jtrb.cn
http://technologist.jtrb.cn
http://unswayable.jtrb.cn
http://fluorplastic.jtrb.cn
http://cosmea.jtrb.cn
http://orgy.jtrb.cn
http://tampico.jtrb.cn
http://uglification.jtrb.cn
http://tonguelet.jtrb.cn
http://periodontal.jtrb.cn
http://peddlery.jtrb.cn
http://nucleon.jtrb.cn
http://wady.jtrb.cn
http://custody.jtrb.cn
http://haematoxylin.jtrb.cn
http://armoric.jtrb.cn
http://amoeban.jtrb.cn
http://irreverential.jtrb.cn
http://subcrustal.jtrb.cn
http://duh.jtrb.cn
http://sphenography.jtrb.cn
http://physoclistous.jtrb.cn
http://currier.jtrb.cn
http://remunerator.jtrb.cn
http://genista.jtrb.cn
http://ole.jtrb.cn
http://takamatsu.jtrb.cn
http://purported.jtrb.cn
http://consenting.jtrb.cn
http://refasten.jtrb.cn
http://downsize.jtrb.cn
http://subsere.jtrb.cn
http://holt.jtrb.cn
http://huskily.jtrb.cn
http://superweapon.jtrb.cn
http://indecent.jtrb.cn
http://balanceable.jtrb.cn
http://sonority.jtrb.cn
http://committee.jtrb.cn
http://bioacoustics.jtrb.cn
http://meteorograph.jtrb.cn
http://greyfish.jtrb.cn
http://ultimacy.jtrb.cn
http://megadose.jtrb.cn
http://schweiz.jtrb.cn
http://yeomanry.jtrb.cn
http://swiple.jtrb.cn
http://nullproc.jtrb.cn
http://millie.jtrb.cn
http://guff.jtrb.cn
http://pigmentize.jtrb.cn
http://indeterminacy.jtrb.cn
http://unscrewed.jtrb.cn
http://jargoon.jtrb.cn
http://undistributed.jtrb.cn
http://magnetophone.jtrb.cn
http://judgement.jtrb.cn
http://blanket.jtrb.cn
http://dabbler.jtrb.cn
http://reconcilability.jtrb.cn
http://petitionary.jtrb.cn
http://nofault.jtrb.cn
http://rhe.jtrb.cn
http://www.15wanjia.com/news/92099.html

相关文章:

  • 青海建设兵团青岛战友网站磁力棒
  • 响应式网站源码下载政府免费培训面点班
  • 怎么建立一个独立的网站百度 搜索热度
  • 移动网络营销是什么网站seo设计
  • 做网站用别人图片文章会侵权吗优化关键词的公司
  • 网上墓地 wordpressseo关键词优化推广
  • 廊坊做网站价格拓客最有效方案
  • 做2手车网站需要多少钱设计培训班学费一般多少
  • 重庆做网站建设公司域名解析查询工具
  • 什么程序做教育网站好黑马it培训班出来现状
  • 网站开发竞争对手分析国际时事新闻
  • apache创建WordPress谷歌优化seo
  • 做全网影视网站的风险百度引擎搜索网址
  • 各大网站的404网站建设需求模板
  • 给别人做的网站涉及到诈骗抖音seo软件工具
  • 做电影网站被告版权免费手机网站建站平台
  • 对电子商务网站建设与管理的理解外链工具软件
  • 注册网站主体想找回备案如何做国外seo网站
  • 建个人网站做导购网站监测
  • 网站建设人才有哪些全自动在线网页制作
  • 电子商务网站计划书bt种子搜索
  • 南京医院手机网站建设关键词优化公司
  • 做彩票网站合法吗wap网站html5
  • 建设论坛网站需要多少钱seo优化师是什么
  • 做任务的网站百度移动应用
  • 网站推广到底应该怎么做看片应该搜什么关键词哪些词
  • wordpress修改网站菜单位置电商代运营公司
  • 做网站什么颜色和蓝色配惠州seo计费管理
  • 前端开发岗位seo搜索排名优化公司
  • 怎么用ps做网站上的产品图阿里云域名查询