发布网友
共9个回答
懂视网
能够为大家提供这些简短而实用的JavaScript技巧来提高大家编程能力,这对于我来说是件很开心的事。每天仅花上不到2分钟的时间中,你将可以读遍JavaScript这门可怕的语言所呈现给我们的特性:performance(性能), conventions(协议), hacks(代码hack), interview questions(面试问题)及所有其他的项。
#24 - 使用 === 代替 ==
==(或者!=)做对比的时候会将进行对比的两者转换到同一类型再比较。===(或者!==)则不会,他会将进行对比的两者做类型对比和值对比,相对于 == ,=== 的对比会更加严谨。
[10] == 10 // true [10] === 10 // false "10" == 10 // true "10" === 10 // false [] == 0 // true [] === 0 // false "" == false // true 但是 true == "a" 是false "" === false // false
#23 - 转换数值的更加的方法
将字符串转换为数字是非常常见的。最简单和最快的(jspref)的方式来实现,将使用+(加)算法。
var one = '1'; var numberOne = +one; // Number 1
你也可以使用-(减号)算法的转换类型并且变成负数值。
var one = '1'; var negativeNumberOne = -one; // Number -1
#22 - 清空一个数组
你定义一个数组,并希望清空它的内容。通常,你会这样做:
var list = [1, 2, 3, 4]; function empty() { //清空数组 list = []; } empty();
但是还有一种更高性能的方法。
你可以使用这些代码:
var list = [1, 2, 3, 4]; function empty() { //清空数组 list.length = 0; } empty();
· list =[] 将一个变量指定个引用到那个数组,而其他引用都不受影响。这意味着,对于先前数组的内容的引用仍然保留在内存中,从而导致内存泄漏。
· list.length = 0 删除数组内的所有东西,这不需要引用任何其他的东西
然而,如果你有一个copy的数组(A和copy-A),如果你使用list.length = 0 删除其内容,副本也会失去它的内容。
var foo = [1,2,3]; var bar = [1,2,3]; var foo2 = foo; var bar2 = bar; foo = []; bar.length = 0; console.log(foo, bar, foo2, bar2); //[] [] [1, 2, 3] []
StackOverflow上的更多详情:difference-between-array-length-0-and-array
#21 - 对数组排序进行"洗牌"(随机排序)
这段代码在这里使用Fisher Yates洗牌算法给一个指定的数组进行洗牌(随机排序)。
function shuffle(arr) { var i, j, temp; for (i = arr.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } return arr; };
案例:
var a = [1, 2, 3, 4, 5, 6, 7, 8]; var b = shuffle(a); console.log(b); // [2, 7, 8, 6, 5, 3, 1, 4]
#20 - 返回对象的函数能够用于链式操作
当创建面向对象的JavaScript对象的function时,函数返回一个对象将能够让函数可链式的写在一起来执行。
function Person(name) { this.name = name; this.sayName = function() { console.log("Hello my name is: ", this.name); return this; }; this.changeName = function(name) { this.name = name; return this; }; } var person = new Person("John"); person.sayName().changeName("Timmy").sayName(); //Hello my name is: John //Hello my name is: Timmy
#19 - 字符串安全连接
假设你有一些类型未知的变量,你想将它们连接起来。可以肯定的是,算法操作不会在级联时应用:
var one = 1; var two = 2; var three = '3'; var result = ''.concat(one, two, three); //"123"
这样的连接不正是你所期望的。相反,一些串联和相加可能会导致意想不到的结果:
var one = 1; var two = 2; var three = '3'; var result = one + two + three; //"33" 而不是 "123"
谈到性能,对join和concat进行比较,他们的执行速度是几乎一样的。你可以在MDN了解更多与concat相关的知识
#18 - 更快的四舍五入
今天的技巧是关于性能。见到过双波浪线"~~"操作符吗?它有时也被称为double NOT运算符。你可以更快的使用它来作为Math.floor()替代品。为什么呢?
单位移~将32位转换输入-(输入+1),因此双位移将输入转换为-(-(输入+1)),这是个趋于0的伟大的工具。对于输入的数字,它将模仿Math.ceil()取负值和Math.floor()取正值。如果执行失败,则返回0,这可能在用来代替Math.floor()失败时返回一个NaN的时候发挥作用。
// 单位移 console.log(~1337) // -1338 // 双位移 console.log(~~47.11) // -> 47 console.log(~~-12.88) // -> -12 console.log(~~1.9999) // -> 1 console.log(~~3) // -> 3 //失败的情况 console.log(~~[]) // -> 0 console.log(~~NaN) // -> 0 console.log(~~null) // -> 0 //大于32位整数则失败 console.log(~~(21474837 + 1) === (21474837 + 1)) // -> 0
虽然~~可能有更好的表现,为了可读性,请使用Math.floor()。
#17 - Node.js:让module在没被require的时候运行
在node里,你可以根据代是运行了require('./something.js')还是node something.js,来告诉你的程序去做两件不同的事情。如果你想与你的一个的模块进行交互,这是很有用的。
if (!module.parent) { // 运行 `node something.js` app.listen(8088, function() { console.log('app listening on port 8088'); }) } else { // 使用 `require('/.something.js')` module.exports = app; }
更多信息,请看the documentation for modules
#16 - 给回调函数传递参数
在默认情况下,你无法将参数传给回调函数,如下:
function callback() { console.log('Hi human'); } document.getElementById('someelem').addEventListener('click', callback);
你可以采取JavaScript闭包的优点来给回调函数传参,案例如下:
function callback(a, b) { return function() { console.log('sum = ', (a+b)); } } var x = 1, y = 2; document.getElementById('someelem').addEventListener('click', callback(x, y));
什么是闭包呢?闭包是指一个针对的(自由)变量的函数。换句话说,闭包中定义的函数会记住它被创建的环境。了解更多请参阅MDN所以这种方式当被调用的时候,参数X/Y存在于回调函数的作用域内。
另一种方法是使用绑定方法。例如:
var alertText = function(text) { alert(text); }; document.getElementById('someelem').addEventListener('click', alertText.bind(this, 'hello'));
两种方法在性能上有一些略微区别,详情参阅jsperf
#15 - 使用更简单的类似indexOf的包含判断方式
原生的JavaScript没有contains方法。对检查字符串或字符串数组项中是否存在某值,你可以这样做:
var someText = 'JavaScript rules'; if (someText.indexOf('JavaScript') !== -1) { } // 或者 if (someText.indexOf('JavaScript') >= 0) { }
但是我们再看看这些ExpressJs代码片段。
// examples/mvc/lib/boot.js for (var key in obj) { // "reserved" exports if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue; // examples/lib/utils.js exports.normalizeType = function(type){ return ~type.indexOf('/') ? acceptParams(type) : { value: mime.lookup(type), params: {} }; }; // examples/web-service/index.js // key is invalid if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key'));
问题是~位运算符。"运算符执行操作这样的二进制表达式,但他们返回标准的JavaScript的数值."
他们将-1转换为0,而0在JavaScript中又是false。
var someText = 'text'; !!~someText.indexOf('tex'); // someText 包含 "tex" - true !~someText.indexOf('tex'); // someText 不包含 "tex" - false ~someText.indexOf('asd'); // someText 不包含 "asd" - false ~someText.indexOf('ext'); // someText 包含 "ext" - true String.prototype.includes()
在ES6(ES 2015)中介绍了includes()方法可以用来确定是否一个字符串包含另一个字符串:
'something'.includes('thing'); // true
在ECMAScript 2016 (ES7)中,甚至数组都可以这样操作,如indexOf:
!!~[1, 2, 3].indexOf(1); // true
[1, 2, 3].includes(1); // true
不幸的是,这只是在Chrome,Firefox,Safari 9或以上的浏览器中被支持。
#14 - arrow 函数(ES6)
介绍下ES6里的新功能,arrow函数可能会是个很方便的工具,用更少行数写更多代码。他的名字来源于他的语法,=>和小箭头->比就像一个“胖胖的箭头”。可能有些人知道,这种函数类型和其他静态语言如lambda表达式的匿名函数。它被称为匿名,因为这些箭头函数没有一个描述性的函数名。
那么这样有什么好处呢?
语法:更少的LOC,不用一次次的键入函数关键字。
语义:从上下文中捕捉关键字this。
简单语法案例:
看看下面的两段代码片段,他们做的是一样的工作。你能很快的理解arrow函数的功能。
// arrow函数的日常语法 param => expression // 可能也会写在括号中 // 括号是多参数要求 (param1 [, param2]) => expression // 使用日常函数 var arr = [5,3,2,9,1]; var arrFunc = arr.map(function(x) { return x * x; }); console.log(arr) // 使用arrow函数 var arr = [5,3,2,9,1]; var arrFunc = arr.map((x) => x*x); console.log(arr)
正如你所看到的,这个例子中的arrow函数可以节省你输入括号内参数和返回关键字的时间。建议把圆括号内的参数输入,如 (x,y) => x+y 。在不同的使用情况下,它只是
用来应对遗忘的一种方式。但是上面的代码也会这样执行:x => x*x.目前看来,这些仅仅是导致更少的LOC和更好的可读性的句法改进。
this 绑定
还有一个更好的理由使用arrow函数。那就是在会出现this问题的背景下。使用arrow函数,你就不用担心.bind(this)和 that=this 了。因为arrow函数会从上下文中找到this。
看下面的例子:
// 全局定义this.i this.i = 100; var counterA = new CounterA(); var counterB = new CounterB(); var counterC = new CounterC(); var counterD = new CounterD(); // 不好的示例 function CounterA() { // CounterA's `this` 实例 (!! 忽略这里) this.i = 0; setInterval(function () { // `this` 指全局对象,而不是 CounterA's `this` // 因此,开始计数与100,而不是0 (本地的 this.i) this.i++; document.getElementById("counterA").innerHTML = this.i; }, 500); } // 手动绑定 that = this function CounterB() { this.i = 0; var that = this; setInterval(function() { that.i++; document.getElementById("counterB").innerHTML = that.i; }, 500); } // 使用 .bind(this) function CounterC() { this.i = 0; setInterval(function() { this.i++; document.getElementById("counterC").innerHTML = this.i; }.bind(this), 500); } // 使用 arrow函数 function CounterD() { this.i = 0; setInterval(() => { this.i++; document.getElementById("counterD").innerHTML = this.i; }, 500); }
关于arrow函数的进一步信息可以看这里 。查看不同的语法选请访问该站点。
#13 - 测量一个JavaScript代码块性能的技巧
快速测量一个JavaScript块的性能,我们可以使用控制台的功能像console.time(label)和console.timeEnd(label)
console.time("Array initialize"); var arr = new Array(100), len = arr.length, i; for (i = 0; i < len; i++) { arr[i] = new Object(); }; console.timeEnd("Array initialize"); //输出: Array initialize: 0.711ms
更多信息Console object, JavaScript benchmarking
demo:jsfiddle-codepen (在浏览器控制台输出)
#12 - ES6中参数处理
在许多编程语言中,函数的参数是默认的,而开发人员必须显式定义一个参数是可选的。在JavaScript中的每个参数是可选的,但我们可以这一行为而不让一个函数利用ES6的默认值作为参数。
const _err = function( message ){ throw new Error( message ); } const getSum = (a = _err('a is not defined'), b = _err('b is not defined')) => a + b getSum( 10 ) // throws Error, b is not defined getSum( undefined, 10 ) // throws Error, a is not defined
_err是立即抛出一个错误的函数。如果没有一个参数作为值,默认值是会被使用,_err将被调用,将抛出错误。你可以在Mozilla开发者网络看到的更多默认参数的例子。
#11 - 提升
理解提升将帮助你组织你的function。只需要记住,变量声明和定义函数会被提升到顶部。变量的定义是不会的,即使你在同一行中声明和定义一个变量。此外,变量声明让系统知道变量存在,而定义是将其赋值给它。
function doTheThing() { // 错误: notDeclared is not defined console.log(notDeclared); //输出: undefined console.log(definedLater); var definedLater; definedLater = 'I am defined!' // 输出: 'I am defined!' console.log(definedLater) // Outputs: undefined console.log(definedSimulateneously); var definedSimulateneously = 'I am defined!' // 输出: 'I am defined!' console.log(definedSimulateneously) // 输出: 'I did it!' doSomethingElse(); function doSomethingElse(){ console.log('I did it!'); } // 错误: undefined is not a function functionVar(); var functionVar = function(){ console.log('I did it!'); } }
为了使事情更容易阅读,在函数作用域内提升变量的声明将会让你明确该变量的声明是来自哪个作用域。在你需要使用变量之前定义它们。在作用域底部定义函数,确保代码清晰规范。
#10 - 检查一个对象是否有属性
当你要检查一个对象是否存在某个属性时,你可能会这样做 :
var myObject = { name: '@tips_js' }; if (myObject.name) { ... }
这是可以的,但你必须知道这个还有两原生的方式,in operator 和 object.hasownproperty,每个对象是对象,既可用方法。每个object都继承自Object,这两个方法都可用。
两个方法的一些不同点:
var myObject = { name: '@tips_js' }; myObject.hasOwnProperty('name'); // true 'name' in myObject; // true myObject.hasOwnProperty('valueOf'); // false, valueOf 是从原型链继承的 'valueOf' in myObject; // true
他们之间的不同在于检查的性质,换句话说,当该对象本身有查找的属性时hasOwnProperty返回yrue,然而,in operator不区分属性创建的对象和属性继承的原型链。
这里有另外一个例子:
var myFunc = function() { this.name = '@tips_js'; }; myFunc.prototype.age = '10 days'; var user = new myFunc(); user.hasOwnProperty('name'); // true user.hasOwnProperty('age'); // false, 因为age是原型链上的
点击看例子。同时,建议在检查对象的属性存在时,阅读这些有关的常见错误。
#09 - 模板字符串
截至ES6,JS已经有模板字符串作为替代经典的结束引用的字符串。
案例:普通字符串
var firstName = 'Jake'; var lastName = 'Rawr'; console.log('My name is ' + firstName + ' ' + lastName); // My name is Jake Rawr 模板字符串: var firstName = 'Jake'; var lastName = 'Rawr'; console.log(`My name is ${firstName} ${lastName}`); // My name is Jake Rawr
在模板字符串中${}中,你可以写不用写/n或者简单逻辑来实现多行字符串。
您还可以使用函数来修改模板字符串的输出,它们被称为模板字符串的标记。你可能还想读到更多的理解模板字符串相关信息。
#08 - 将节点列表转换为数组
querySelectorAll 方法返回一个和数组类似的节点列表对象。这些数据结构类似数组,因为经常以数组形式出现,但是又不能用数组的方法,比如map和foreach。这里是一个快速、安全、可重用的方式将一个节点列表到一个DOM元素数组:
const nodelist = document.querySelectorAll('p'); const nodelistToArray = Array.apply(null, nodelist); //later on .. nodelistToArray.forEach(...); nodelistToArray.map(...); nodelistToArray.slice(...); //etc...
apply方法是将一系列数组格式的参数传递给一个给定this的函数。MDN指出,apply将会调用类似数组的对象,而这正是querySelectorAll所返回的。因为我们不需要在函数的上下文中指定this,所以我们传入null或0。返回的结果是一组能使用数组方法的DOM元素数组。
如果你使用的是es2015可以利用...(spread operator)
const nodelist = [...document.querySelectorAll('p')]; // 返回的是个真实的数组 //later on .. nodelist.forEach(...); nodelist.map(...); nodelist.slice(...); //etc...
#07 - "use strict" 和懒惰
严格模式的JavaScript让开发人员更加安全的编写JavaScript。
默认情况下,JavaScript允许开发者懒惰,例如,我们在第一次声明变量的时候可以不用var,虽然这可能看起来像一个没有经验的开发人员,同时这也是很多错误的根源,变量名拼写错误或意外地将它提到了外部作用域。
程序员喜欢让电脑为我们做些无聊的事,检查一些我们工作的错误。"use strict"指令我们做这些,将我们的错误转换成JavaScript的错误。
我们把这个指令可以通过添加在一个js文件的顶部:
// 整个script文件都将是严格模式语法 "use strict"; var v = "Hi! I'm a strict mode script!"; 或者在函数内: function f() { // 函数范围内的严格模式语法 'use strict'; function nested() { return "And so am I!"; } return "Hi! I'm a strict mode function! " + nested(); } function f2() { return "I'm not strict."; }
在包含这个指令的JavaScript文件或者函数内,我们将一些较大的JavaScript项目中的不良行为直接在JavaScript引擎执行中禁止了。在其他情况中,严格模式改变以下的行为:
· 变量只有在前面 var 声明了才能用
· 试图写入只读属性产生的误差
· 必须用 new 关键字调用构造函数
· this 不会默认指向全局对象
· 非常有限的使用eval()
· 保护保留字符或未来保留字符不被作为变量名使用
严格模式在新项目中是很有好处的,但是在大多数地方没使用到它的老项目里使用它是非常具有挑战性的。当你把多个文件合并到一个文件时,它也是个问题,就像可能导致整个文件都在严格模式下执行。
它不是一个声明,只是一个字面量,早期版本的浏览器会忽略它。严格模式支持:
· IE 10+
· FF 4+
· Chrome 13+
· Safari 5.1+
· Opera 12+
参阅MDN对于严格模式的描述。
#06 - 处理一个数组或单个元素作为参数的方法
相比于写个单独的方法去分别操作一个数组和一个元素作为参数的函数,更好的是写一个通用的函数,这样就都可以操作。这类似于一些jQuery的方法(css匹配将修改所有的选择器)。
你仅需要先将一切放进数组,Array.concat会接收数组或单一的对象:
function printUpperCase(words) { var elements = [].concat(words); for (var i = 0; i < elements.length; i++) { console.log(elements[i].toUpperCase()); } }
printUpperCase现在可以接收无论单一的元素作为参数还是一个数组:
printUpperCase("cactus"); // => CACTUS printUpperCase(["cactus", "bear", "potato"]); // => CACTUS // BEAR // POTATO
#05 - undefined 和 null 的不同
· undefined指的是一个变量未被声明,或者一个变量被声明但未赋值
· null是指一个特定的值,即"没有值"
. JavaScript给未赋值的变量默认定义为undefined
· JavaScript不会给未赋值的变量设置null值,它被程序员用来表示一个无价值的值
· undefined在json格式数据中是无效的,而null有效
· undefined 类型是 undefined
· null类似是object.为什么呢?
· 两者都是原始值
· 两者都被认为false(Boolean(undefined) // false, Boolean(null) // false)。
· 辨认变量是不是undefined
typeof variable === "undefined"
· 检查变量是不是null
variable === "null"
从值考虑他们是相等的,但是从类型和值共同考虑他们是不相等的
null == undefined // true
null === undefined // false
#04 - 以非ASCII字符形式来排序字符串
JavaScript有个原生的方法对字符串格式的数组进行排序,做一个简单的array.sort()将会把字符串们按首字母的数序排列。当然,也可以提供自定义排序功能。
['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); // ["Buenos Aires", "Mumbai", "New York", "Shanghai"]
当你试图用非ASCII字符,如 ['é', 'a', 'ú', 'c']这样的进行排序,你会得到一个奇怪的结果['c', 'e', 'á', 'ú'],因为只有用英语的语言才能排序,所以发生这种情况。
看一个简单的例子:
// Spanish ['único','árbol', 'cosas', 'fútbol'].sort(); // ["cosas", "fútbol", "árbol", "único"] // 错误的排序 // German ['Woche', 'w?chentlich', 'w?re', 'Wann'].sort(); // ["Wann", "Woche", "w?re", "w?chentlich"] // 错误的排序
幸运的是,有两种方法来避免这种行为,ECMAScript国际化的API提供了localecompare和and Intl.Collator。
这两种方法都有自己的自定义参数,以便将其配置来充分的完成功能。
使用 localeCompare()
['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) { return a.localeCompare(b); }); // ["árbol", "cosas", "fútbol", "único"] ['Woche', 'w?chentlich', 'w?re', 'Wann'].sort(function (a, b) { return a.localeCompare(b); }); // ["Wann", "w?re", "Woche", "w?chentlich"]
使用 intl.collator()
['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare); // ["árbol", "cosas", "fútbol", "único"] ['Woche', 'w?chentlich', 'w?re', 'Wann'].sort(Intl.Collator().compare); // ["Wann", "w?re", "Woche", "w?chentlich"]
· 每个方法都可以自定义位置
· 在FF浏览器,intl.collator()会更快,当比较的是较大的数值或字符串
因此,当你在用英语以外的语言来赋值给字符串数组时,记得要使用此方法来避免意外的排序。
#03 - 改善嵌套条件
我们怎样才能改善并且使JavaScript中的if语句做出更有效的嵌套。
if (color) { if (color === 'black') { printBlackBackground(); } else if (color === 'red') { printRedBackground(); } else if (color === 'blue') { printBlueBackground(); } else if (color === 'green') { printGreenBackground(); } else { printYellowBackground(); } }
一个改善的办法是用switch语句代替嵌套的if语句。虽然它是更加简洁,更加有序,但不推荐这样做,因为很难debug。这里指出原因。
switch(color) { case 'black': printBlackBackground(); break; case 'red': printRedBackground(); break; case 'blue': printBlueBackground(); break; case 'green': printGreenBackground(); break; default: printYellowBackground(); }
但是,当我们有多个判断条件的情况下呢?在这种情况下,如果我们想让它更加简洁,更加有序,我们可以使用switch。如果我们将true的作为一个参数传递给该switch语句,它可以让我们在每一个情况下放置一个条件。
switch(true) { case (typeof color === 'string' && color === 'black'): printBlackBackground(); break; case (typeof color === 'string' && color === 'red'): printRedBackground(); break; case (typeof color === 'string' && color === 'blue'): printBlueBackground(); break; case (typeof color === 'string' && color === 'green'): printGreenBackground(); break; case (typeof color === 'string' && color === 'yellow'): printYellowBackground(); break; }
但我们必须避免在每一个条件下进行多次检查,尽量避免使用switch。我们也必须考虑到最有效的方法是通过一个object。
var colorObj = { 'black': printBlackBackground, 'red': printRedBackground, 'blue': printBlueBackground, 'green': printGreenBackground, 'yellow': printYellowBackground }; if (color in colorObj) { colorObj[color](); }
这里有更多相关的信息。
#02 - ReactJs 子级构造的keys是很重要的
keys是代表你需要传递给动态数组的所有组件的一个属性。这是一个独特的和指定的ID,react用它来标识每个DOM组件以用来知道这是个不同的组件或者是同一个组件。使用keys来确保子组件是可保存的并且不是再次创造的,并且防止怪异事情的产生。
· 使用已存在的一个的对象值
· 定义父组件中的键,而不是子组件
//不好的 ... render() { <p key={{item.key}}>{{item.name}}</p> } ... //好的 <MyComponent key={{item.key}}/> · 使用数组不是个好习惯 · random()从不会执行 //不好的 <MyComponent key={{Math.random()}}/>
· 你可以创建你的唯一id,请确保该方法是快速的并已经附加到对象上的
· 当子级的数量是庞大的或包含复杂的组件,使用keys来提高性能
· 你必须为所有的子级ReactCSSTransitionGroup提供key属性
#01 - AngularJs: $digest vs $apply
AngularJs最让人欣赏的特点是双向数据绑定。为了是它工作,AngularJs评估模型的变化和视图的循环($digest)。你需要了解这个概念,以便了解框架是如何在引擎中工作的。
Angular评估每时的每个事件的变化。这就是$digest循环。有时你必须手动运行一个新的循环,你必须有正确的选择,因为这个阶段是性能方面表现出最具影响力的。
$apply
这个核心方法让你来启动一个$digest循环。这意味着所以的watch列表中的对象都将被检查,整个应用程序启动了$digest循环。在内部,执行可选的函数参数之后,调用$rootScope.$digest();
$digest
在这种情况下,$digest方法在当前作用域和它的子作用域执行,你应该注意到,父级的作用域将不被检查,并没有受到影响。
建议:
· 只在浏览器DOM事件在Angular之外被触发的时候使用$apply或者$digest
· 给$apply传递函数表达式,这有一个错误处理机制,允许在消化周期中整合变化。
$scope.$apply(() => { $scope.tip = 'Javascript Tip'; });
· 如果你仅仅想更新当前作用域或者他的子作用域,用$digest,并且防止整个应用程序的$digest。性能不言而喻咯。
· 当$apply有很多东西绑定时,这对机器来说是个艰难的过程,可能会导致性能问题。
· 如果你使用的是Angular 1.2.x以上的,使用$evalAsync。这是一个在当前循环或下一次循环的期间或对表达式做出评估的核心方法,这可以提高你的应用程序的性能。
#00 - 在数组插入一个项
将一个项插入到现有数组中,是一个日常常见的任务,你可以使用push在数组的末尾添加元素,使用unshift在开始的位置,或者在中间使用splice。
这些都是已知的方法,但这并不意味着没有一个更高性能的途径。我们来看一看。
在数组的末尾添加一个元素很容易与push(),但还有一个更高性能的途径。
var arr = [1,2,3,4,5]; arr.push(6); arr[arr.length] = 6; //在Chrome 47.0.2526.106 (Mac OS X 10.11.1)上提高了 43% 的速度
这两种方法都修改了数组,不相信我?看这个jsperf
现在,如果我们正在尝试将一个项目添加到数组的开头:
var arr = [1,2,3,4,5]; arr.unshift(0); [0].concat(arr); //在Chrome 47.0.2526.106 (Mac OS X 10.11.1)上提高了 98% 的速度
这里更详细一点:unshift编辑原有的数组,concat返回一个新数组。jsperf
添加在阵列中的物品很容易使用splice,它是做它的最高效的方式。
var items = ['one', 'two', 'three', 'four']; items.splice(items.length / 2, 0, 'hello');
相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!
推荐阅读:
JS发送json格式POST请求实现步奏
根据环境传递参数方法选择不同域名
热心网友
用毛刷或滚刷直接将JS防水涂料涂刷在基面上,力度运用均匀,不能漏刷;若用于防潮,只需涂刷一层;用于防水,需涂刷二至三层。 当第一层JS防水涂料干固至刚好不粘手时(通常须1-2小时),即可涂刷第二层,每两层涂刷方向应笔直相交。如果家中有防水这个需求的话,可以去了解一下科顺这个品牌。科顺防水科技股份有限公司成立于1996年,历经二十余年的稳健经营和高效发展,现已成长为以提供防水综合解决方案为主业,集工程建材、民用建材、建筑修缮业务板块于一体,业务范围涵盖海内外的综合建材公司。
科顺防水已形成以防水材料研发、制造、销售为主体,包括技术服务和工程服务的多业态组合,公司现为中国建筑防水协会副会长单位,已连续10年当选“房地产500强首选防水材料品牌”,先后与碧桂园、万科、融创中国、绿地控股、中海、世茂、龙湖集团、招商蛇口等超过100家知名房企签订战略合作协议,行业综合实力排名前三。
热心网友
1、配料 JS-I型打底层涂料的重量配比为液料:粉料:水=1:1.2:1;下层、中层和上层涂料的重量配比为液料:粉料:水=1:1.2:0.2;面层涂料可加颜料以形成彩色层,彩色层涂料的重量配比为液料:粉料:颜料:水=1:1.2:0.1:0.2。JS-II型打底层配料为液料:粉料:水=1:1.6:1;中层和上层配料为液料:粉料:水=1:1.6:0.3。涂料应充分搅拌均匀,使之不含粉团。 2、涂覆 用滚子或刮板涂覆,按顺序逐层完成。各层之间的时间间隔以前一层涂膜干固不粘为准。涂覆时应注意以下事项: 2.1、涂料(尤其是底涂)有沉淀应随时搅拌均匀; 2.2、涂覆要尽量均匀,不能有局部沉积,并要求多滚刷几次,使涂料与基层之间不留气泡,粘接严实。 2.3、每层涂覆必须按规定用量取料,不能过厚或过薄,若最后防水厚度不够,可加涂一层或数层。 3、保护层与装饰层施工 JS-I型保护层或装饰层施工须在防水层完工2天后进行,粘贴块材(如地板、瓷砖、马赛克等)时,将JS涂料按液料:粉料=1:2调成腻子状,即可用作胶粘剂。JS-II型可在面层施工同时贴保护层。 4、质量要求与工程检验 防水层施工完毕后,应认真检验整个工程的各个部分,特别是薄弱环节,发现问题及时修复,涂层不应有裂纹、翘边、鼓泡、分层等现象。 蓄水试验须等涂层完全干固后方可进行,一般情况下需48h以上,在特别潮湿又不通风的环境中需更长时间。厕浴间防水做完后,蓄水24h不渗漏为合格。屋面防水做完后,应检查排水系统是否畅通、有无渗漏(可在雨后或持续淋水2h以后进行,有条件蓄水的屋面可用24h蓄水检查)。
热心网友
先将液料倒入干净容器中,然后边搅拌边将粉料倒入搅拌桶内,充分拌至均匀无结块,然后进行涂抹,涂层应均匀,每一层施工须等上一层略为干固后进行,加网格布需在底层未固化前铺放,并迅速涂刷后一层。
一、大致流程:
基层清理→涂刷底面防水层→阴阳角等复杂部位加筋布施工→涂刷中层防水层→涂刷表面防水层→工程质量验收。
二、施工方法:
①基层清理:先用铲刀和笤帚及工具将基层表面的突起物、砂浆或疙瘩等铲除并将尘土杂物清扫干净。
②涂刷底面防水层:JS乳液需与水泥搅拌均匀。
③用滚刷或油漆刷均匀地涂刷底层,不得漏底,一般用量为0.6~1kg/㎡。待涂层干固后,才能进行下道工序。
三、涂刷JS防水层:
将配制好的防水涂料均匀涂刷在基层表面,涂刷2~3遍。
①涂覆时应注意以下事项:若液料有沉淀应随时搅拌均匀;
②涂覆应尽量均匀,不能有局部沉积,不能过厚或过薄,涂料与基层之间不留有气泡,粘结严实。
③每层涂覆必须按照规定用量取料,较薄处不低于1.2mm。
④涂层硬化后,马上进行保温养护,保证涂层潮湿,以防粉化。
四、JS防水涂料介绍:
JS防水涂料是指聚合物水泥防水涂料,又称JS复合防水涂料。其中,J就是指聚合物,S水泥("JS"为"聚合物水泥"的拼音字头)。JS防水涂料是一种以聚丙烯酸酯乳液、乙烯-醋酸乙烯酯共聚乳液等聚合物乳液与各种添加剂组成的有机液料,和水泥、石英砂、轻重质碳酸钙等无机填料及各种添加剂所组成的无机粉料通过合理配比、复合制成的一种双组份、水性建筑防水涂料。
五、主要特点介绍:
1、湿面施工;涂层坚韧高强。
2、加入颜料可做成彩色装饰层。
3、无毒、无味,可用于食用水池的防水。
4、适用于有饰面材料外墙、斜屋面的防水,立面、斜面和顶面上施工, 能与基面及饰面砖、屋面瓦、水泥砂浆等各种外层材料牢固粘结。
5、耐高温(140℃),尤其适用于道路及桥梁防水。
6、调整配合比,可制作瓷砖粘结材料和密封材料。
热心网友
JS防水涂料广泛用于外墙、厨卫、游泳池、地下室屋面及其他建筑物的防水,防渗漏,防潮等工程。
产品优点:产品性能稳定,易干施工/抗渗;无味无污染;施工安全;简单;粘接性能优异;耐高/低温 抗紫外线。
施工方法
1.施工前准备:
1.1基层处理:施工要求平整、干净、坚定牢固、无尘土、油污,阴阳角要做成R角,如:基面有起孔,蜂窝裂缝等缺陷的要先进行修补,干燥基面,需经湿润处理。
1.2底涂处理;在基面上先涂一遍纯防水胶。
1.3防水涂料配置:按照乳液:普通硅酸盐水泥=1:(1.8~2.5)的比例配置好,用低速搅拌至均匀细腻,不含颗粒的混合物即可使用。
2.施工步骤:
2.1每层涂刷方向要统一,第二层应与第一层不同:例如第一层横向涂刷,第二层则应纵向涂刷,以此类推每层施工方向。
2.2每层涂刷厚度以0.4-0.7mm为宜。
2.3均匀涂覆第一层,使其与基面完全粘接。第一层干燥后(约1-2小时,以不沾手为宜)方可施工第二层。
2.4大面积施工时,应多遍涂刷,通常为3-4遍,特殊工程5遍及以上。
2.5高风险区应做增强附加层。
3.施工要点/*:
3.1施工温度宜在5℃以上,施工时要保持施工环境空气流通。
3.2聚合物在使用前应搅拌均匀。
3.3应采用普通硅酸盐水泥(R32.5级)。
4.检查
施工完成后,待防水涂层干燥完全后,可进行闭水试验(时间24-48小时)以此来检验防水施工是否合格。
热心网友
先将液料倒入干净容器中,然后边搅拌边将粉料倒入搅拌桶内,充分拌至均匀无结块,然后进行涂抹,涂层应均匀,每一层施工须等上一层略为干固后进行,加网格布需在底层未固化前铺放,并迅速涂刷后一层
热心网友
1、配料 JS-I型打底层涂料的重量配比为液料:粉料:水=1:1.2:1;下层、中层和上层涂料的重量配比为液料:粉料:水=1:1.2:0.2;面层涂料可加颜料以形成彩色层,彩色层涂料的重量配比为液料:粉料:颜料:水=1:1.2:0.1:0.2。JS-II型打底层配料为液料:粉料:水=1:1.6:1;中层和上层配料为液料:粉料:水=1:1.6:0.3。涂料应充分搅拌均匀,使之不含粉团。 2、涂覆 用滚子或刮板涂覆,按顺序逐层完成。各层之间的时间间隔以前一层涂膜干固不粘为准。涂覆时应注意以下事项: 2.1、涂料(尤其是底涂)有沉淀应随时搅拌均匀; 2.2、涂覆要尽量均匀,不能有局部沉积,并要求多滚刷几次,使涂料与基层之间不留气泡,粘接严实。 2.3、每层涂覆必须按规定用量取料,不能过厚或过薄,若最后防水厚度不够,可加涂一层或数层。 3、保护层与装饰层施工 JS-I型保护层或装饰层施工须在防水层完工2天后进行,粘贴块材(如地板、瓷砖、马赛克等)时,将JS涂料按液料:粉料=1:2调成腻子状,即可用作胶粘剂。JS-II型可在面层施工同时贴保护层。 4、质量要求与工程检验 防水层施工完毕后,应认真检验整个工程的各个部分,特别是薄弱环节,发现问题及时修复,涂层不应有裂纹、翘边、鼓泡、分层等现象。 蓄水试验须等涂层完全干固后方可进行,一般情况下需48h以上,在特别潮湿又不通风的环境中需更长时间。厕浴间防水做完后,蓄水24h不渗漏为合格。屋面防水做完后,应检查排水系统是否畅通、有无渗漏(可在雨后或持续淋水2h以后进行,有条件蓄水的屋面可用24h蓄水检查)。
热心网友
楼固合易涂是一款全新的多功能防水涂料,具有防水,固砂,粘接的三大功能,能成功解决传统双组份带来的繁琐施工的问题,也可以解决单组份不能直接贴砖的难题,同时还能解决聚氨酯防水跟水泥不亲和的特性,可以一次性解决卫生间防水重复用料施工的成本。是一款真正的新型复合功能防水涂料。
热心网友
施工工艺:
1.将液体添加剂倒入干净的搅拌容器中,然后按比例一边搅拌一边缓慢加入粉料,充分搅拌3-5分钟直至生成无粉团的、均匀的胶浆。
2.用辊子、刷子将浆料均匀涂刷于处理好的底材上,根据使用环境及性能要求涂刷2层或2层以上; 一般工程防水层厚度为1mm,地下工程施工规范厚度要求为1.5-2mm。
3.做完一层后,必须待其略为干固(刚好不粘手)后,再做第二层,一般需1-3小时,具体情况视基面的密实度以及当时的气温而定。如果超过24小时,或涂层已经固化,在其上涂刷第二层时,必须先用清水重新润湿表面。
4.养护固化:浆料涂刷后第二天起,建议用细雾喷水或湿布覆盖涂层2-3天,再进行闭水试验;
工法1: 基面-打底层-下涂层-上涂层
工法2:基面-打底层-下涂层-无纺布层-中涂层-上涂层