造成这样结果的原因有多样,而其中之一的原因,是由于 js 缺乏类型系统,导致我们无法通过工具来在开发的过程中检测到那些可能会发生的错误,也无法通过具体的类型定义来约束别人如何调用自己写的代码库。...当然我今天要讲的并不是 typescript,而是由 facebook 推出的flow。...type cannot be added to strA arrF; ^^^^ string flow 除了可以自动的进行类型推断外,还可以通过类型声明的来进一步限制代码的行为,例如我们声明一个函数..." val; } hello("world"); hello(1); 但如果我们希望我们的函数只接受 string 作为参数,并且明确返回 string,则可以 function hello(...这时 SublimeLinter-flow 就会在当前文件夹向上查找.flowconfig 文件,并对带有 // [@flow] 的文件进行自动检测,如果出现错误,就会直接在编辑器上提示,十分的方便。
'goods' of undefined 这种错误也是再正常不过了,如果说是res数据是自己定义,那么可控性会大一些,但是如果这些数据来自于不同端(如前后端),那么这种数据对于我们来说我们都是不可控的...// invokes the function `a` otherwise 二、通过函数解析字符串 我们可以通过函数解析字符串来解决这个问题,这种实现就是lodash的 _.get 方法 var object...=== null || val === undefined) break; parent = val; val = val[path[i...]] } if(val === null || val === undefined) { val = args[0...综上,在实际工作中,使用方法四会是最优雅,可读性也非常强,但考虑到浏览器的话,可能方法二会更加常用,当然,如果你所要取的值层级不是太深,你组内的同事要严格的lint,方法三也不失为一种好的选择。
) { return typeof val === "object" && val !...核心思想: 调用call 的可能不是函数 this 可能传入 null 传入不固定个数的参数 给对象绑定函数并调用 删除绑定的函数 函数可能有返回值 实现: Function.prototype.call1...核心思想: 调用bind的可能不是函数 bind() 除了 this 外,还可传入多个参数 bind() 创建的新函数可能传入多个参数 新函数可能被当做构造函数调用 函数可能有返回值 实现: Function.prototype.bind1...val = /^\d+$/.test(val) ?...Static 关键字有了解嘛 为这个类的函数对象直接添加方法,而不是加在这个函数对象的原型对象上 如果一个构造函数,bind了一个对象,用这个构造函数创建出的实例会继承这个对象的属性吗?为什么?
链式运算符,不同之处在于,在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。...与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。 mdn 语法: obj.val?.prop obj.val?.[expr] obj.func?....运算符,JavaScript 会在尝试访问 obj.first.second 之前,先隐式地检查并确定 obj.first 既不是 null 也不是 undefined。...undefined : temp.second); 可选链与函数调用 函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。...(); 注: 如果存在一个属性名且不是函数,使用 ?. 仍然会产生一个 TypeError 异常 (x.y is not a function). 处理可选的回调函数或者事件处理器 使用?.
test(val) ?...Promise.all 的错误信息。...如果不是Promise,调用新Promise的resolve函数 result instanceof Promise ?...this, 'rejected', reason2)() }.bind(this) ) } else { // 拥有then 但是then不是一个函数..., 注意错误穿透用的是throw而不是return,否则的话 // 这个then返回的promise状态将变成resolved即接下来的then中的onFullfilled // 会被调用, 然而我们想要调用的是
将es6转换成es5 npm i @babel/core @babel/cli @babel/preset-env babel-loader --save-dev 以上几个通常是babel需要安装的,...module: { rules: [ { test: /\.js$/, use: [ { loader: 'babel-loader...那为什么memorize这个工具函数可以优化程序的性能 当我们看到这段代码是不是感觉很熟悉 export const memorize = callback => { let cache = false...=> { if (isType(val)('String')) { return val; } if (isType(val)('Array')) {...const ret = []; // todo 辅助函数,递归数组内部, 这里递归可以考虑用分时函数来代替优化 const loopFn = (val) => {
== 'function') { // 不是函数,就赋值一个啥也不干的函数 onFulfilled = value => value;...== 'function') { // 失败参数不是函数,就赋值一个怎么做都是错的函数 onRejected = reason => {...== 'function') { // 不是函数,就赋值一个啥也不干的函数 onFulfilled = value => value;...== 'function') { // 失败参数不是函数,就赋值一个怎么做都是错的函数 onRejected = reason => {...== 'function') { // 不是函数,就赋值一个啥也不干的函数 onFulfilled = value => value;
// 定义空函数 function noop() {} // 用来存储错误信息 var IS_ERROR = {} // 获取实例的then function getThen(obj) { try...== 'object') { throw new TypeError('Promises must be constructed via new'); } // 校验Promise的构造函数..._noop = noop; 当使用new操作符实例化Promise的时候,必须传入Promise的构造函数fn,否则将抛出错误 然后初始化实例的状态和值 最后调用doResolve方法 下面我们一起来看一下...一开始先判断实例的构造函数是不是Promise(防止外部修改prototype.constructor) 这里的safeThen函数不作过多解释,主要用于实例化外部实例的构造函数并返回实例 创建一个空的...= Promise.prototype.then) { ... } 如果传进来的val不是Promise且包含then方法,则 else { // 如果不是promise的实例且包含then
如果 onFulfilled 不是函数,则必须忽略它; 如果 onRejected 不是函数,则必须忽略它; 代码如下: class MyPromise { then(onFulfilled,...3.2 resolvePromise Promises/A+ 规范 对resolvePromise 的要求如下: 如果 promise2 === x, 执行 reject,错误原因为 TypeError...如果 x 是函数或对象 如果 x.then 是函数 执行 x.then 如果 x.then 不是函数 执行 resolve(x) 如果 x 不是函数或对象 执行 resolve(x) 代码如下: function...resolvePromise (promise2, x, resolve, reject) { // 如果 promise2 === x, 执行 reject,错误原因为 TypeError...if (called) return reject(error) } } else { // 如果 x.then 不是函数
然后昨晚就在家里装了个3.X的版本,很悲催的发现,原来写的有很多的错误,万般无奈的检查之下,发现语句上是没什么问题,只是3.X版本不兼容部分的语句,例如最常用的print,raw_input都不一样了,...但如果在圆括号中同时输出多个对象时,就会创建一个元组,这是因为在Python 2中,print是一个语句,而不是函数调用。...所以,我还是会在Python 3的脚本中尝试用float(3)/2或 3/2.0代替3/2,以此来避免代码在Python 2环境下可能导致的错误(或与之相反,在Python 2脚本中用from __...: unorderable types: list() > str() 返回可迭代对象,而不是列表 在xrange一节中可以看到,某些函数和方法在Python中返回的是可迭代对象,而不像在Python...x = 10000000 def val_in_range(x, val): return val in range(x) def val_in_xrange(x, val): return
备注:应当直接在 Object 构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用。...返回值 被传递给函数的对象。...存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。 这两种描述符都是对象。...该函数的返回值会被用作属性的值。 默认为 undefined。set属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。...arc.temperature = 11; arc.temperature = 13; arc.getArchive(); // [{ val: 11 }, { val: 13 }] 下面这个例子中,getter
但是没关系,我们可以站在巨人的肩膀上,要相信我们现在要走的路,前人都走过,所以可以找找现在社区已经存在的那些优秀的文章,比如工业聚大佬写的 100 行代码实现 Promises/A+ 规范,找到这些文章后不是收藏夹吃灰...val = /^\d+$/.test(val) ?...对象,返回 Date 的 toJSON 字符串值; 如果是普通对象; 对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。..."b":2}'; var obj = eval("(" + json + ")"); // obj 就是 json 反序列化之后得到的对象 但是直接调用 eval 会存在安全问题,如果数据中可能不是...onFulfilled : (v) = > v; // 因为错误的值要让后面访问到,所以这里也要抛出错误,不然会在之后 then 的 resolve 中捕获 onRejected
descriptor:将被定义或修改的属性描述符 返回值:被传递给函数的对象。...数据描述符:是一个具有值的属性,该值可能是可写的,也可能不是可写的。 存取描述符:是由getter-setter函数对描述的属性。 描述符必须是这两种形式之一;不能同时是两者。...如示例所示,试图写入非可写属性不会改变它,也不会引发错误。...如果o.a的configurable属性为true,则不会抛出任何错误,并且该属性将在最后被删除。...arc.temperature = 11; arc.temperature = 13; arc.getArchive(); // [{ val: 11 }, { val: 13 }] 或var pattern
可以使用partial而不是lambda为函数提供默认参数,有些参数可以不指定。 1.1.1 部分对象 第一个例子显示了函数myfunc()的两个简单partial对象。...method2()未被定义为绑定方法,所以必须显式传递self参数;否则,这个调用会导致TypeError。...('ERROR: {}'.format(err)) 如果将一个不能散列的对象传入这个函数,则会产生一个TypeError。...空列表会生成一个错误,除非提供一个initializer参数。...如果默认值与新值结合没有意义,那么最好是捕获TypeError而不是传入一个initializer参数。
] = param.split('='); // 分割 key 和 value val = decodeURIComponent(val); // 解码 val = /^\d+$/....test(val) ?...如果该函数只有一个参数,当参数为对象时,直接返回该对象;当参数不是对象时,会先将参数转为对象然后返回。...如果不是Promise,调用新Promise的resolve函数 result instanceof Promise ?...=> resolve(val), err => reject(err), ) }) }) }}手写 apply 函数apply 函数的实现步骤:判断调用对象是否为函数
可以使用 new 关键字实例化一个空的 WeakSet: const ws = new WeakSet(); 弱集合中的值只能是 Object 或者继承自 Object 的类型,尝试使用非对象设置值会抛出 TypeError...如果想在初始化时填充弱集合,则构造函数可以接收一个可迭代对象,其中需要包含有效的值。..., val2]); 只要有一个值无效就会抛出错误,导致整个初始化失败: const ws = new WeakSet([{ id: 1 }, true, { id: 2 }]); // TypeError...(val1).add(val2); ws.has(val1); // true 4. delete() delete(): 删除某个元素(返回布尔值): const val1 = { id: 1 },...val2 = { id: 2 }; const ws = new WeakSet(); ws.add(val1).add(val2); ws.delete(val1); // true 弱值
如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。...一般来说不应该能够获取到这个值的,但是现在浏览器中都实现了 proto 属性来访问这个属性,但是最好不要使用这个属性,因为它不是规范中规定的。...对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。...onFulfilled : (v) = > v; // 因为错误的值要让后面访问到,所以这里也要抛出错误,不然会在之后 then 的 resolve 中捕获 onRejected...当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。
安装包如下:npm i webpack webpack-cli babel-core(babel 核心模块) babel-loader(解析 js) @babel/preset-env(转 es5) @..."development", module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader...val[key] = deepProxy(val[key], handler) } return new Proxy(val, handler())}我们注意下 deepProxy 中的递归处理,我们不是如果这个值为对象就进行代理...放在 set 改值之后执行,这样 autorun 函数中就能拿到最新的属性值 reaction.run() return val }, get(target...const observable = (target, key, descritor) => { // 如果不是装饰器,只有第一个参数就可以了,我们这里简单用第二个参数判断 if(typeof key
即迭代器可以迭代不是序列但表现出序列行为的对象, 例如字典的 key , 一个文件的行, 等等。迭代器有以下特性: 提供了可扩展的迭代器接口. 对列表迭代带来了性能上的增强. 在字典迭代中性能提升....创建真正的迭代接口, 而不是原来的随机对象访问. 与所有已经存在的用户定义的类以及扩展的模拟序列和映射的对象向后兼容 迭代非序列集合(例如映射和文件)时, 可以创建更简洁可读的代码....按照一种不是很准确的说法,两个实体经常被当做一个,合起来叫做生成器。...使用示例: def Zrange(n): i = 0 while i < n: val = yield i print "val is", val...核心编程》 中生成器表达式一节,作者在原书中只用了一行代码来实现这个功能,即: return max(len(x.strip()) for x in open('/etc/motd')) 这行代码会报出如下错误
领取专属 10元无门槛券
手把手带您无忧上云