Open huangyingzheng opened 4 years ago
setTimeout 和 setTimeInterval 都是延迟执行,但是本质是不同的。或者说是延迟一点时间加入任务队列,但是执行时间不一定。
而setTimeInterval 如果发现有相同的任务同样任务队列,任务就会丢失,而且如果执行时间大于间隔时间,两个interval执行时间就没有间隔了。
可以这样
let timer = setTimeout( function() {
timer = setTimeout( function() {})
},10)
嵌套执行,可以保证第一个执行完第二个才会加入任务队列,也一定会有至少10ms gap
bind 用法,改变函数this指向
function bar() {
return this.value
}
const foo = {
value: 10
}
bar.call(foo)
10
模拟开始
使用 '.' attribute, 所以需要用Function.prototype.
Function.prototype.call2 = function(ct) {
let context = ct || Window //如果传入的是null,指向window
context.fn = this
let args = []
for(let i = 1; i < arguments.length; i++){
args.push('arguments[' + i + ']') // 类数组
}
let result = eval('context.fn('+args+')')
delete context.fn
return result
}
bar.call2(foo)
10
apply 和call 类似
Function.prototype.apply = function (context, arr) {
var context = context || window;
context.fn = this;
var result;
if (!arr) {
result = context.fn();
}
else {
var args = [];
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')')
}
delete context.fn
return result;
}
关于变量对象相关描述
function fun3() {
console.log('fun3')
}
function fun2() {
fun3();
}
function fun1() {
fun2();
}
fun1();
Const gs= []
Gs.push( fun1, functionContext)
Gs.push(fun2, fc)
Gs.push(fun3,fc)
Gs.pop()
Gs.pop()
Gs.pop()
//进入globalContext
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
ECStack.push(<checkscope> functionContext);
ECStack.push(<f> functionContext);
ECStack.pop();
ECStack.pop();
只有在执行的是否才会开启执行上下文
变量对象会包括:
console.log(a)// fn
function a() {
}
var a = 10
console.log(a)// 10
闭包和上下文环境 执行
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
var foo = checkscope();
foo();
进入全局代码,创建全局执行上下文,全局执行上下文压入执行上下文栈 全局执行上下文初始化 执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 执行上下文被压入执行上下文栈 checkscope 执行上下文初始化,创建变量对象、作用域链、this等 checkscope 函数执行完毕,checkscope 执行上下文从执行上下文栈中弹出 执行 f 函数,创建 f 函数执行上下文,f 执行上下文被压入执行上下文栈 f 执行上下文初始化,创建变量对象、作用域链、this等 f 函数执行完毕,f 函数上下文从执行上下文栈中弹出
在function f
被创建的时候f.[[scope]]
中就已经保存了 globalContext.VO
和 checkscope.AO
所以 foo执行的时候能访问到 var scope = "local scope"
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i);
};
}
data[0]();
data[1]();
data[2]();
这里有几个点需要注意,第一个是data[i] 和 console.log(i) 两个i访问的地址是不一样的,第一个i
我理解为 simple assignment ,使用的是getValue返回的是具体的值,所以i
马上被确定下来了。第二个i
是在执行时从作用域链上面找的。
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
scope = '1'
return f;
}
var foo = checkscope();
foo(); // ‘1’
// 上面这个例子说明的就是,说明执行的时候后面传入的值会替换前面的值。
在data[0]() 执行的时候之前,globalContest.VO ={ data: [], i:3},而data[0]创建的执行上下文 =》
{ AO:{
length: 0 },
Scope:[ AO, globalContext.VO]}
可以看到是没有i
的,所以要从gloableContext.Vo中拿,这里的i已经被确定为3了,那么data0,1,2执行的结果都是3.
解决的方法有两个,第一个是将var改成let
第二个是用闭包在作用域链上再加一层,一个立即执行的匿名函数var data = [];
for (var i = 0; i < 3; i++) {
data[i] = (function(i){
return function(){
console.log(i)
}
})(i)
}
data[0]();
data[1]();
data[2]();
Data0 的执行上下文变成:[ AO,匿名函数.AO globalContext.VO], 因为是立即执行的,i传入是被保留。
正在学习使用 Taro,其中需要一些数据网上公开的api无法提供,所以使用mockjs模拟一些数据,然后拦截axios请求。 简单讲一下步骤
先将一个Mock 文件夹,里面包含index文件
将package.json里面的script里面加一个 mock: ./mock 指令
index里面调用mock的方法有两种
const Mock = import('mockjs')
const result = Mock.mock( '/url/url/url' , 'get', data)
//data是返回的数据比如
const data = {
status: 200,
data: {
list:[]
}
}
module.export = result
const Query = (options, dataSource) => {
let { current, pageSize, ...other } = options;
current = current || 1;
pageSize = pageSize || 10;
for (let key in other) {
if ({}.hasOwnProperty.call(other, key)) {
dataSource = dataSource.filter(item => {
if ({}.hasOwnProperty.call(item, key)) {
return String(item[key]).trim().indexOf(decodeURI(other[key]).trim()) > -1
}
return true
})
}
}
return { current, pageSize, dataSource }
}
const data = { 'GET /api/book/list': (req, res) => { const { query } = req; const { current, pageSize, dataSource } = Query(query, BookData.data.lists); res.status('200').json({ data: { lists: dataSource.slice((current - 1) pageSize, current pageSize), pageInfo: { current: Number(current), pageSize: Number(pageSize), total: dataSource.length, maxCurrent: dataSource.length % pageSize >= 0 ? Math.ceil(dataSource.length / pageSize) : dataSource.data.length / pageSize } }, statusCode: '200' }) } } module.export = data
- Mock.Random 制作数据,具体可以看官网,或者【https://juejin.im/post/6844903860343963655#heading-12】,总结的很好。
```javascript
const Random=Mock.Random;
{
'Boolean': Random.boolean, // 随机生成布尔类型
'Natural': Random.natural(1, 100), // 随机生成1到100之间自然数
'Integer': Random.integer(1, 100), // 生成1到100之间的整数
'Float': Random.float(0, 100, 0, 5), // 生成0到100之间的浮点数,小数点后尾数为0到5位
'Character': Random.character(), // 生成随机字符串,可加参数定义规则
'String': Random.string(2, 10), // 生成2到10个字符之间的字符串
'Range': Random.range(0, 10, 2), // 生成一个数组,数组元素从0开始到10结束,间隔为2
'Date': Random.date(), // 生成一个随机日期,可加参数定义日期格式,默认yyyy-mm-dd
'Image1': Random.image(Random.size, '#02adea', '#fff','png','Hello'), // Random.size表示将从size数据中任选一个数据,生成Random.size指定大小的,背景为'#02adea'的,前景色为'#fff'的,格式为'png'的,内容为'Hello'的图片。
'Image2':Random.dataImage('200x100', 'Hello Mock.js!'),//只设置大小
'Color': Random.color(), // 生成一个颜色随机值
'Paragraph':Random.paragraph(2, 5), //生成2至5个句子的文本
'Name': Random.name(), // 生成姓名
'Url': Random.url(), // 生成url地址
'Address': Random.province() // 生成地址
}
let template = {
'Boolean': Random.boolean, // 可以生成基本数据类型
'Natural': Random.natural(1, 100), // 生成1到100之间自然数
'Integer': Random.integer(1, 100), // 生成1到100之间的整数
'Float': Random.float(0, 100, 0, 5), // 生成0到100之间的浮点数,小数点后尾数为0到5位
'Character': Random.character(), // 生成随机字符,可加参数定义规则
'String': Random.string(2, 10), // 生成2到10个字符之间的字符串
'Range': Random.range(0, 10, 6), // 生成一个随机数组
'Date': Random.date(), // 生成一个随机日期,可加参数定义日期格式
'Image': Random.image(Random.size, '#02adea', '#fff','png','Hello'),
'Color': Random.color(), // 生成一个颜色随机值
'Paragraph':Random.paragraph(2, 5), //生成2至5个句子的文本
'Name': Random.name(), // 生成姓名
'Url': Random.url(), // 生成web地址
'Address': Random.province() // 生成地址
}
// 尾调用和柯里化
function url(protocol, hostname, pathname) {
return `${protocol}${hostname}${pathname}`;
}
const url1 = url('https://', 'www.juejin.im', '/user/yan');
const url2 = url('https://', 'www.juejin.im', '/user/tong');
const url3 = url('https://', 'www.juejin.im', '/user/shao');
//上面这个函数中,前两个参数都是一样的,可以对其进行复用
function curryUrl(protocol) {
return function(hostname, pathname){
return function(pathname){
return ${protocol}${hostname}${pathname}
;
}
}
}
const urlHttps = curryUrl('https://'); const urlHosts = urlHttps('www.juejin.im');
const url1 = urlHosts('/user/yan'); const url2 = urlHosts( '/user/tong'); const url3 = urlHosts( '/user/shao');
function add() { let args = [...arguments]; // 第一次的arguments console.log(arguments); let num = function () { args.push(...arguments); // 之后每次的arguments return num; // 每次的结果指向自己,保证多次调用保证后面跟着多个括号可以执行 };
num.toString = function () { return args.reduce(function (pre, cur) { return pre + cur; }); }; return num; } console.log(add(1, 2, 3)(4)(7).toString());
第一次记录:
伢羽关于(业务类前端的困局)技术和业务之间的联系,自己总结为以下几点: