Home >Backend Development >PHP Tutorial >Sharing some js tips
This article mainly shares some js tips with you. The article is a bit long, I hope it can help everyone.
1. JavaScript fault-tolerant processing code (shielding js errors)
<span style="font-size: 14px;"><script language="javascript"><br/> <!-- /*屏蔽所有的js错误*/<br/> function killerrors() {<br/> return true;<br/> }<br/> window.onerror = killerrors; //--></script><br/></span>
I can provide you with these short and practical JavaScript skills to improve your programming ability, which is very important to me It's a very happy thing. In less than 2 minutes a day, you will be able to read through the features that this terrible language of JavaScript presents to us: performance, conventions, hacks, interview questions question) and all other items.
== (or !=). When comparing, the two objects being compared will be Or convert to the same type and compare again. === (or !==) does not. It will compare the types and values of the two being compared. Compared with ==, the comparison of === will be more rigorous.
[10] == 10 // true
[10] === 10 // false
“10” == 10 // true
“10” === 10 // false
[] == 0 // true
[] === 0 // false
"" == false // true but true == "a" is false
"" == = false // false
Converting strings to numbers is very common. The simplest and fastest (jspref) way to do it, would be to use the + (plus) algorithm.
var one = '1';
var numberOne = +one; // Number 1
You can also use -( minus sign) algorithm's conversion type and becomes a negative value.
var one = '1';
var negativeNumberOne = -one; // Number -1
You define an array and want to clear its contents. Typically, you would do this:
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] []
More details on StackOverflow: difference-between-array-length-0-and-array
This code uses the Fisher Yates shuffling algorithm to shuffle a specified array (randomly sort) ).
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; };
Case:
?
1
2
3
4
##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]
When creating functions for object-oriented JavaScript objects, returning an object from the function will allow functions to be chained together for execution.
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
Assuming you have some Variables of unknown type and you want to concatenate them. To be sure, algorithmic operations are not applied when cascading:
var one = 1; var two = 2;
var three = '3';
var result = ”.concat(one, two, three); //”123”
Such a connection is not what you expect. Instead, some concatenation and phase Adding may lead to unexpected results:
var one = 1; var two = 2;
var three = '3';
var result = one + two + three; //"33" instead of "123"
Talking about performance, comparing join and concat, their execution speed is almost the same. You can. Learn more about concat at MDN
Today’s tip is about performance. The double tilde "~~" operator? It is sometimes called the double NOT operator. You can use it as a faster replacement for Math.floor(). Why? Bit-shifting the input -(input+1), so a double shift will transform the input to -(-(input+1)), which is a great tool for going to 0. For input numbers, it will mimic Math.ceil(). Takes a negative value and Math.floor() takes a positive value and returns 0 if the execution fails. This may be used instead of returning a NaN when Math.floor() fails. // 单位移
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(
(2147483647 + 1) === (2147483647 + 1)) // -> 0
##Although~~may have better performance, for readability, use Math.floor()
.
在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
在默认情况下,你无法将参数传给回调函数,如下:
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
原生的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或以上的浏览器中被支持。
介绍下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函数的进一步信息可以看这里 。查看不同的语法选请访问该站点。
快速测量一个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 (在浏览器控制台输出)
在许多编程语言中,函数的参数是默认的,而开发人员必须显式定义一个参数是可选的。在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开发者网络看到的更多默认参数的例子。
理解提升将帮助你组织你的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!’); } }
为了使事情更容易阅读,在函数作用域内提升变量的声明将会让你明确该变量的声明是来自哪个作用域。在你需要使用变量之前定义它们。在作用域底部定义函数,确保代码清晰规范。
当你要检查一个对象是否存在某个属性时,你可能会这样做 :
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是原型链上的
点击看例子。同时,建议在检查对象的属性存在时,阅读这些有关的常见错误。
截至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(<span style="font-size: 14px;">My name is ${firstName} ${lastName}</span>
);
// My name is Jake Rawr
在模板字符串中${}中,你可以写不用写/n或者简单逻辑来实现多行字符串。
您还可以使用函数来修改模板字符串的输出,它们被称为模板字符串的标记。你可能还想读到更多的理解模板字符串相关信息。
The querySelectorAll method returns a node list object similar to an array. These data structures are similar to arrays because they often appear in the form of arrays, but array methods such as map and foreach cannot be used. Here's a fast, safe, reusable way to convert a nodelist to an array of DOM elements:
const nodelist = document.querySelectorAll('p');
const nodelistToArray = Array.apply(null, nodelist);
//later on ..
nodelistToArray.forEach(…);
nodelistToArray.map(…);
nodelistToArray.slice(…);
//etc…
The apply method is to pass a series of parameters in array format to a function given this. MDN points out that apply will call an array-like object, which is what querySelectorAll returns. Because we don't need to specify this in the context of the function, we pass in null or 0. The returned result is an array of DOM elements that can be used using array methods.
If you are using es2015 you can use...(spread operator)
const nodelist = […document.querySelectorAll('p') ]; // Returns a real array
//later on ..
nodelist.forEach(…);
nodelist.map(…);
nodelist.slice(…);
//etc…
Strict mode JavaScript allows developers to write JavaScript more safely .
By default, JavaScript allows developers to be lazy. For example, we can not use var when declaring a variable for the first time. Although this may look like an inexperienced developer, it is also the source of many errors. Variables The name is misspelled or accidentally mentioned in an outer scope.
Programmers like to let the computer do boring things for us and check some errors in our work. "use strict" instructs us to do this and convert our errors into JavaScript errors.
We can add this instruction at the top of a js file:
// The entire script file will be strict mode syntax
"use strict";
var v = "Hi! I'm a strict mode script!";
Or within a function:
function f()
{
// Strict mode syntax within function scope
'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.”; }
In the JavaScript file or function containing this directive, We've disabled bad behavior in some larger JavaScript projects directly in JavaScript engine execution. Among other things, strict mode changes the following behavior:
· Variables can only be used if they are declared with var
· Errors caused by trying to write to read-only properties
· The constructor must be called with the new keyword
· this will not point to the global object by default
· Very limited use of eval()
· Protect reserved characters or future reserved characters from being used as variable names
Strict mode is beneficial in new projects, but it can be very challenging to use it in older projects where it is not used in most places. It's also a problem when you merge multiple files into one, as it can cause the entire file to execute in strict mode.
It is not a declaration, just a literal, and earlier versions of browsers will ignore it. Strict mode support:
· IE 10+
· FF 4+
· Chrome 13+
· Safari 5.1+
· Opera 12+
See MDN's description of strict mode.
Compared to writing a separate method to operate an array and a single element respectively A function that takes an element as a parameter is better to write a general function so that it can be operated on. This is similar to some jQuery methods (css matching will modify all selectors).
You just need to put everything into an array first, Array.concat will accept an array or a single object:
function printUpperCase(words) {
var elements = [] .concat(words);
for (var i = 0; i 1b697c2705175b79da5fe06caf83bd62 CACTUS
printUpperCase(["cactus", " bear", "potato"]);
// => CACTUS
// BEAR
// POTATO
· undefined refers to a variable that has not been declared, or a variable that has been declared but not assigned a value
· null refers to a specific value, that is, "no value"
. JavaScript defaults to undefined for unassigned variables
· JavaScript will not set null values for unassigned variables. It is used by programmers to represent a worthless value
· Undefined is in json format data Invalid, while null is valid
· undefined type is undefined
· null is similar to object. Why?
· Both are primitive values
· Both are considered false(Boolean(undefined) // false, Boolean(null) // false).
· Identify whether the variable is undefined
typeof variable === “undefined”
· Check whether the variable is null
variable === "null"
They are equal from the value point of view, but they are not equal from the type and value point of view
null == undefined // true
null === undefined // false
JavaScript has a native Method to sort an array in string format. Doing a simple array.sort() will sort the strings in alphabetical order. Of course, custom sorting capabilities are also available.
['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); // ["Buenos Aires", "Mumbai" , "New York", "Shanghai"]
When you try to use non-ASCII characters, such as ['é', 'a', 'ú', 'c'] Doing the sorting, you get a weird result ['c', 'e', 'á', 'ú'], this happens because sorting is possible only in English.
Look at a simple example:
// Spanish ['único','árbol', 'cosas', ' fútbol'].sort();
// ["cosas", "fútbol", "árbol", "único"] // Wrong sorting
// German
['Woche', ' wöchentlich', 'wäre', 'Wann'].sort();
// ["Wann", "Woche", "wäre", "wöchentlich"] // Wrong sorting
Fortunately, there are two ways to avoid this behavior. The ECMAScript internationalization API provides localecompare and Intl.Collator. Both methods have their own custom parameters so that they can be configured to fully function.
Use 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"]
Use 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"]
· Each method can customize the position
· In FF browser, intl.collator() will be faster, when the comparison is Large numbers or stringsSo, when you assign to a string array in a language other than English, remember to use this method to avoid accidental sorting.
How can we improve and make more efficient nesting of if statements in JavaScript.
if (color) { if (color === 'black') {
printBlackBackground();
} else if (color === ' red') {
printRedBackground();
} else if (color === 'blue') {
printBlueBackground();
} else if (color === 'green') {
printGreenBackground();
} else {
printYellowBackground();
}
}
An improvement is to use switch statements instead of nested if statements. Although it is cleaner and more organized, it is not recommended because it is difficult to debug. Here’s why.
switch(color) {
case 'black':
printBlackBackground();
break;
case 'red':
printRedBackground( );
break;
case 'blue':
printBlueBackground();
break;
case 'green':
printGreenBackground();
break;
default:
printYellowBackground();
}
But what about when we have multiple judgment conditions? In this case, if we want to make it more concise and orderly, we can use switch. If we pass true as a parameter to the switch statement, it allows us to place a condition in each case.
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;
}
But we must avoid multiple checks under each condition and try to avoid using switch. We must also consider that the most efficient method is through an object.
var colorObj = {
'black': printBlackBackground,
'red': printRedBackground,
'blue': printBlueBackground,
'green': printGreenBackground,
'yellow': printYellowBackground
};
if (color in colorObj) {
colorObjcolor;
}
Here are more Related information.
keys is one that represents all the components that you need to pass to the dynamic array Attributes. This is a unique and specific ID that React uses to identify each DOM component to know whether it is a different component or the same component. Use keys to ensure that child components are saved and not recreated, and to prevent weird things from happening.
· Use an existing independent object value
· Define the key in the parent component, not the child component
/ /Bad
…
render() {
{{item.name}}
}
…
//Good
· Using arrays is not a good practice
· random() never executes
//Bad
· You can create your unique id, please make sure the method is fast and has been attached to the object
· When the number of children is huge or contains complex components, use keys to improve Performance
· You must provide the key attribute for all children of ReactCSSTransitionGroup
The most admirable feature of AngularJs is two-way data binding. In order for it to work, AngularJs evaluates model changes and view loops (
digest loop. Sometimes you have to manually run a new Loop, you must have the right choice as this phase is the one that shows the most impact in terms of performance
##$apply
##. The core method lets you start a##digest loop, which internally calls
# after executing the optional function arguments.##digest();
$digest
在这种情况下,$digest方法在当前作用域和它的子作用域执行,你应该注意到,父级的作用域将不被检查,并没有受到影响。
建议:
· 只在浏览器DOM事件在Angular之外被触发的时候使用
digest
· 给$apply传递函数表达式,这有一个错误处理机制,允许在消化周期中整合变化。
apply(() => {
$scope.tip = ‘Javascript Tip’;
});
· 如果你仅仅想更新当前作用域或者他的子作用域,用
digest。性能不言而喻咯。
· 当
evalAsync。这是一个在当前循环或下一次循环的期间或对表达式做出评估的核心方法,这可以提高你的应用程序的性能。
将一个项插入到现有数组中,是一个日常常见的任务,你可以使用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,它是做它的最高效的方式。
?
1
2
var items = [‘one’, ‘two’, ‘three’, ‘four’];
items.splice(items.length / 2, 0, ‘hello’);
我试着在不同的浏览器和操作系统中运行这些测试,结果是相似的。我希望这些建议对你有用,鼓励你自己做测试!
<span style="font-size: 14px;"><script language="javascript"><br/> <!-- /*屏蔽所有的js错误*/<br/> function killerrors() {<br/> return true;<br/> }<br/> window.onerror = killerrors; //--></script><br/></span>
能够为大家提供这些简短而实用的JavaScript技巧来提高大家编程能力,这对于我来说是件很开心的事。每天仅花上不到2分钟的时间中,你将可以读遍JavaScript这门可怕的语言所呈现给我们的特性:performance(性能), conventions(协议), hacks(代码hack), interview questions(面试问题)及所有其他的项。
==(或者!=)做对比的时候会将进行对比的两者转换到同一类型再比较。===(或者!==)则不会,他会将进行对比的两者做类型对比和值对比,相对于 == ,=== 的对比会更加严谨。
[10] == 10 // true
[10] === 10 // false
“10” == 10 // true
“10” === 10 // false
[] == 0 // true
[] === 0 // false
“” == false // true 但是 true == “a” 是false
“” === false // false
将字符串转换为数字是非常常见的。最简单和最快的(jspref)的方式来实现,将使用+(加)算法。
var one = ‘1’;
var numberOne = +one; // Number 1
You can also use the - (minus) algorithm conversion type and become a negative value.
var one = '1';
var negativeNumberOne = -one; // Number -1
You define an array and want to clear its contents. Usually, you would do this:
var list = [1, 2, 3, 4];
function empty() {
//Empty the array
list = [];
}
empty();
But there is a more performant way.
You can use these codes:
var list = [1, 2, 3, 4];
function empty() {
//Empty the array
list.length = 0;
}
empty();
· list =[] specifies a reference to a variable to that array, while other references are Not affected. This means that references to the contents of the previous array still remain in memory, causing a memory leak.
· list.length = 0 deletes everything inside the array, this does not require a reference to anything else
However, if you have a copied array (A and copy-A), if you use list.length = 0 deletes its contents, the copy also loses its contents.
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] []
More details on StackOverflow: difference-between-array-length-0-and-array
This code uses the Fisher Yates shuffling algorithm to shuffle (randomly sort) a specified array.
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;
};
Case:
?
1
2
3
4
##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]
When creating functions for object-oriented JavaScript objects, returning an object from the function will enable functions to be chained together for execution.
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
Suppose you have some variables of unknown type, You want to connect them. To be sure, algorithmic operations are not applied when cascading:
var one = 1; var two = 2;
var three = '3';
var result = ”.concat(one, two, three); //”123”
Such a connection is not what you expect. Instead, some concatenation and phase Adding may lead to unexpected results:
var one = 1; var two = 2;
var three = '3';
var result = one + two + three; //"33" instead of "123"
Talking about performance, comparing join and concat, their execution speed is almost the same. You can. Learn more about concat at MDN
Today’s tip is about performance. The double tilde "~~" operator? It is sometimes called the double NOT operator. You can use it as a faster replacement for Math.floor(). Why? Bit-shifting the input -(input+1), so a double shift will transform the input to -(-(input+1)), which is a great tool for going to 0. For input numbers, it will mimic Math.ceil(). Takes a negative value and Math.floor() takes a positive value and returns 0 if the execution fails. This may be useful instead of returning a NaN when Math.floor() fails.
//Unit shift
console.log(~1337) // -1338
//Double shift
console.log(47.11) // -> 47
console.log(-12.88) // -> -12
console.log(1.9999) // -> 1
console.log(~~3) // -> 3
//Failure situation
console.log([]) // -> 0
console.log(NaN) // -> 0
console.log(~~null) // -> 0
//Fail if it is greater than 32-bit integer
console.log((2147483647 + 1) === (2147483647 + 1) ) // -> 0
Although ~~ may have better performance, for readability, use Math.floor().
In node, you can run it according to the code require('./something.js') or node something.js, to tell your program to do two different things. This is useful if you want to interact with one of your standalone modules.
if (!module.parent) {
// Run <span style="font-size: 14px;">node something.js</span>
app.listen(8088, function() {
console.log('app listening on port 8088');
})
} else {
// Use <span style="font-size: 14px;">require('/.something.js')</span>
module.exports = app;
}
More information , please see the documentation for modules
By default, you cannot pass parameters to the callback function The function is as follows:
function callback() {
console.log('Hi human');
}
document.getElementById('someelem'). addEventListener('click', callback);
You can take advantage of JavaScript closures to pass parameters to the callback function. The case is as follows:
function callback(a, b) {
return function() {
console.log('sum = ', (a+b));
}
}
var x = 1, y = 2;
document.getElementById('someelem').addEventListener('click', callback(x, y));
What is a closure? A closure is a function over independent (free) variables. In other words, the function defined in the closure remembers the environment in which it was created. See MDN for more information. So this way, when called, the parameters X/Y exist within the scope of the callback function.
Another way is to use the binding method. For example:
var alertText = function(text) {
alert(text);
};
document.getElementById('someelem').addEventListener(' click', alertText.bind(this, 'hello'));
There are some slight differences in performance between the two methods. For details, please refer to jsperf
Native JavaScript does not have a contains method. To check whether a value exists in a string or string array item, you can do this:
var someText = 'JavaScript rules';
if (someText.indexOf(' JavaScript') !== -1) {
}
// or
if (someText.indexOf('JavaScript') >= 0) {
}
But let’s look at these ExpressJs code snippets again.
// 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: {} }; };
// key is invalid if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key'));
They convert -1 to 0, which is false in JavaScript. var someText = 'text'; Introduced in ES6 (ES 2015), the includes() method can be used to determine whether a string contains Another string: ##'something'.includes('thing'); // true in ECMAScript 2016 (ES7) , even arrays can be operated in this way, such as indexOf: !!~[1, 2, 3].indexOf(1); // true [1, 2, 3].includes(1); // true Unfortunately, this is only supported in Chrome, Firefox, Safari 9 or above. Introducing the new functions in ES6, the arrow function may be a very convenient tool. Use Write more code in fewer lines. His name comes from his syntax, where => looks like a "fat arrow" compared to the small arrow ->. Some of you may know that this function type is similar to anonymous functions in other static languages such as lambda expressions. It's called anonymous because these arrow functions don't have a descriptive function name. So what are the benefits of this? Syntax: Less LOC, no need to type function keywords again and again. Semantics: Capture the keyword this from the context. Simple syntax example: Look at the two code snippets below, they do the same job. You can quickly understand the function of the arrow function. // Daily syntax of arrow function param => expression // Use daily functions var arr = [5,3,2,9,1]; // Use arrow function var arr = [5,3,2,9,1]; As you can see, the arrow function in this example saves you time entering the parameters in parentheses and the return keyword. It is recommended to enter the parameters in parentheses, such as (x,y) => x+y. In different use cases, it is just a way to deal with forgetting. But the above code will also execute like this: x => x*x. For now, it seems that these are just syntactic improvements that lead to less LOC and better readability. this binding There is a better reason to use the arrow function. That is the context in which this problem arises. Using the arrow function, you don't have to worry about .bind(this) and that=this. Because the arrow function will find this from the context. Look at the following example: // Globally define this.i this.i = 100; var counterA = new CounterA(); var counterC = new CounterC(); var counterD = new CounterD(); this Further information about the arrow function can be found here. To see the different syntax options visit this site. To quickly measure the performance of a JavaScript block, we can use the console function like console.time(label) and console.timeEnd(label) console.time(“Array initialize”); #_err is a function that immediately throws an error. If there is no argument as a value, the default value will be used, _err will be called, and an error will be thrown. You can see more examples of default parameters on the Mozilla Developer Network. Understanding boost will help you organize your functions. Just remember that variable declarations and defining functions are hoisted to the top. Variable definitions will not work, even if you declare and define a variable on the same line. Furthermore, a variable declaration lets the system know that a variable exists, whereas a definition assigns a value to it. function doTheThing() { To make things easier to read, hoisting a variable declaration within a function scope will make it clear which scope the variable is declared from. Define variables before you need to use them. Define functions at the bottom of the scope to ensure clear and standardized code. When you want to check if an object has a certain property, you might do this : ##var myObject = { name: '@tips_js' This is possible, but you must know that there are two native methods, in operator and object.hasownproperty. Each object is an object and has available methods. Every object inherits from Object, and both methods are available. Some differences between the two methods: var myObject = { name: '@tips_js' The difference between them lies in the nature of the check. In other words, when the object itself has the property to be looked up, hasOwnProperty returns yrue , however, the in operator does not distinguish between the object created by the property and the prototype chain from which the property is inherited. Here is another example: var myFunc = function() { this.name = '@tips_js'; 点击看例子。同时,建议在检查对象的属性存在时,阅读这些有关的常见错误。 截至ES6,JS已经有模板字符串作为替代经典的结束引用的字符串。 var firstName = ‘Jake’; 在模板字符串中${}中,你可以写不用写/n或者简单逻辑来实现多行字符串。 The querySelectorAll method returns a node list object similar to an array. These data structures are similar to arrays because they often appear in the form of arrays, but array methods such as map and foreach cannot be used. Here's a fast, safe, reusable way to convert a nodelist to an array of DOM elements: const nodelist = document.querySelectorAll('p'); The apply method is to pass a series of parameters in array format to a function given this. MDN points out that apply will call an array-like object, which is what querySelectorAll returns. Because we don't need to specify this in the context of the function, we pass in null or 0. The returned result is an array of DOM elements that can be used using array methods. If you are using es2015 you can use...(spread operator) const nodelist = […document.querySelectorAll('p') ]; // Returns a real array Strict mode JavaScript allows developers to write JavaScript more safely . Programmers like to let the computer do boring things for us and check some errors in our work. "use strict" instructs us to do this and convert our errors into JavaScript errors. We can add this instruction at the top of a js file: // The entire script file will be strict mode syntax In the JavaScript file or function containing this directive, We've disabled bad behavior in some larger JavaScript projects directly in JavaScript engine execution. Among other things, strict mode changes the following behavior: · Variables can only be used if they are declared with var Strict mode is beneficial in new projects, but it can be very challenging to use it in older projects where it is not used in most places. It's also a problem when you merge multiple files into one, as it can cause the entire file to execute in strict mode. · IE 10+ See MDN's description of strict mode. Compared to writing a separate method to operate an array and a single element respectively A function that takes an element as a parameter is better to write a general function so that it can be operated on. This is similar to some jQuery methods (css matching will modify all selectors). function printUpperCase(words) { · undefined refers to a variable that has not been declared, or a variable that has been declared but not assigned a value typeof variable === “undefined” variable === "null" null == undefined // true JavaScript has a native Method to sort an array in string format. Doing a simple array.sort() will sort the strings in alphabetical order. Of course, custom sorting capabilities are also available. ['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); // ["Buenos Aires", "Mumbai" , "New York", "Shanghai"] When you try to use non-ASCII characters, such as ['é', 'a', 'ú', 'c'] Doing the sorting, you get a weird result ['c', 'e', 'á', 'ú'], this happens because sorting is possible only in English. Look at a simple example: // Spanish ['único','árbol', 'cosas', ' fútbol'].sort(); Fortunately, there are two ways to avoid this behavior. The ECMAScript internationalization API provides localecompare and Intl.Collator. Both methods have their own custom parameters so that they can be configured to fully function. Use localeCompare() ['único','árbol', 'cosas', 'fútbol'].sort(function ( a, b) { return a.localeCompare(b); Use intl.collator() ['único','árbol ', 'cosas', 'fútbol'].sort(Intl.Collator().compare); // ["árbol", "cosas", "fútbol", "único"] · Each method can customize the position · In FF browser, intl.collator() will be faster, when the comparison is Large numbers or stringsSo, when you assign to a string array in a language other than English, remember to use this method to avoid accidental sorting. How can we improve and make more efficient nesting of if statements in JavaScript. if (color) { if (color === 'black') { An improvement is to use switch statements instead of nested if statements. Although it is cleaner and more organized, it is not recommended because it is difficult to debug. Here’s why. switch(color) { But what about when we have multiple judgment conditions? In this case, if we want to make it more concise and orderly, we can use switch. If we pass true as a parameter to the switch statement, it allows us to place a condition in each case. switch(true) { But we must avoid multiple checks under each condition and try to avoid using switch. We must also consider that the most efficient method is through an object. if (color in colorObj) { Here are more Related information. keys is one that represents all the components that you need to pass to the dynamic array Attributes. This is a unique and specific ID that React uses to identify each DOM component to know whether it is a different component or the same component. Use keys to ensure that child components are saved and not recreated, and to prevent weird things from happening. · Use an existing independent object value / /Bad {{item.name}} } · You can create your unique id, please make sure the method is fast and has been attached to the object The most admirable feature of AngularJs is two-way data binding. In order for it to work, AngularJs evaluates model changes and view loops ( digest loop. Sometimes you have to manually run a new Loop, you must have the right choice as this phase is the one that shows the most impact in terms of performance ##$apply ##digest loop, which internally calls ##digest(); $digest 在这种情况下,$digest方法在当前作用域和它的子作用域执行,你应该注意到,父级的作用域将不被检查,并没有受到影响。 · 只在浏览器DOM事件在Angular之外被触发的时候使用 digest
apply(() => { · 如果你仅仅想更新当前作用域或者他的子作用域,用 digest。性能不言而喻咯。 evalAsync。这是一个在当前循环或下一次循环的期间或对表达式做出评估的核心方法,这可以提高你的应用程序的性能。 将一个项插入到现有数组中,是一个日常常见的任务,你可以使用push在数组的末尾添加元素,使用unshift在开始的位置,或者在中间使用splice。 这些都是已知的方法,但这并不意味着没有一个更高性能的途径。我们来看一看。 这两种方法都修改了数组,不相信我?看这个jsperf var arr = [1,2,3,4,5]; 这里更详细一点:unshift编辑原有的数组,concat返回一个新数组。jsperf var items = [‘one’, ‘two’, ‘three’, ‘four’]; 我试着在不同的浏览器和操作系统中运行这些测试,结果是相似的。我希望这些建议对你有用,鼓励你自己做测试!
!!~someText.indexOf('tex'); // someText contains "tex" - true
!~someText.indexOf('tex') ; // someText does not contain "tex" - false
~someText.indexOf('asd'); // someText does not contain "asd" - false
~someText.indexOf('ext'); // someText includes "ext" - true
String.prototype.includes()12 - arrow function (ES6)
// May also be written in parentheses
// Parentheses are multi-parameter requirements
(param1 [, param2]) => expression
var arrFunc = arr.map(function(x) {
return x * x;
});
console.log(arr)
var arrFunc = arr.map((x) => x*x);
console.log(arr )
// Bad example
function CounterA() { // CounterA's
instance (!! Ignore this) this.i = 0; <span style="font-size: 14px;">setInterval(function () { </span>//
this
refers to the global object, not CounterA's <span style="font-size: 14px;"></span>this
// Therefore, start counting with 100 instead of 0 (local this.i) <span style="font-size: 14px;">this.i++; </span>document.getElementById ("counterA").innerHTML = this.i;
}, 500);
} // Manual binding that = this
function CounterB() {
this.i = 0;
var that = this;
setInterval(function() {
that.i++;
document.getElementById(“counterB”).innerHTML = that.i;
}, 500 );
}
// Use .bind(this)
function CounterC() {
this.i = 0;
setInterval(function() {
this.i++;
document.getElementById(“counterC”).innerHTML = this.i;
}.bind(this), 500);
}
//Use arrow function
function CounterD() {
this.i = 0;
setInterval(() => {
this.i++;
document.getElementById(“counterD”).innerHTML = this.i;
} , 500);
}13 - Tips for measuring the performance of a JavaScript block
var arr = new Array(100),
len = arr.length,
i;
for (i = 0; i 0d1df530e26441869a263e65c6ebca79 a + b
getSum( 10 ) // throws Error, b is not defined
getSum( undefined, 10 ) // throws Error , a is not defined15 - Boost
// Error: notDeclared is not defined
console.log(notDeclared);
// Output: undefined
console .log(definedLater);
var definedLater;
definedLater = 'I am defined!'
// Output: 'I am defined!'
console.log(definedLater)
// Outputs: undefined
console.log(definedSimulateneously);
var definedSimulateneously = 'I am defined!'
// Output: 'I am defined!'
console.log(definedSimulateneously)
// Output: 'I did it!'
doSomethingElse();
function doSomethingElse(){
console.log('I did it!');
}
// Error : undefined is not a function
functionVar();
var functionVar = function(){
console.log('I did it!');
}
}16 - Check if an object has a property
};
if (myObject.name) { … }
};
myObject.hasOwnProperty('name'); // true
'name' in myObject; // true
myObject.hasOwnProperty('valueOf'); // false, valueOf is inherited from the prototype chain
'valueOf' in myObject; // true
};
myFunc. prototype.age = '10 days';
var user = new myFunc();
user.hasOwnProperty('name'); // true
user.hasOwnProperty('age'); // false , because age is
on the prototype chain17 - 模板字符串
案例:普通字符串
var lastName = ‘Rawr’;
console.log(‘My name is ’ + firstName + ’ ’ + lastName);
// My name is Jake Rawr
模板字符串:
var firstName = ‘Jake’;
var lastName = ‘Rawr’;
console.log(<span style="font-size: 14px;">My name is ${firstName} ${lastName}</span>
);
// My name is Jake Rawr
您还可以使用函数来修改模板字符串的输出,它们被称为模板字符串的标记。你可能还想读到更多的理解模板字符串相关信息。18- Convert the node list to an array
const nodelistToArray = Array.apply(null, nodelist);
//later on ..
nodelistToArray.forEach(…);
nodelistToArray.map(…);
nodelistToArray.slice(…);
//etc…
//later on ..
nodelist.forEach(…);
nodelist.map(…);
nodelist.slice(…);
//etc…#19 - “use strict” and lazy
By default, JavaScript allows developers to be lazy. For example, we can not use var when declaring a variable for the first time. Although this may look like an inexperienced developer, it is also the source of many errors. Variables The name is misspelled or accidentally mentioned in an outer scope.
"use strict";
var v = "Hi! I'm a strict mode script!";
Or within a function:
function f()
{
// Strict mode syntax within function scope
'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.”; }
· Errors caused by trying to write to read-only properties
· The constructor must be called with the new keyword
· this will not point to the global object by default
· Very limited use of eval()
· Protect reserved characters or future reserved characters from being used as variable names
It is not a declaration, just a literal, and earlier versions of browsers will ignore it. Strict mode support:
· FF 4+
· Chrome 13+
· Safari 5.1+
· Opera 12+20 - Methods that handle an array or a single element as a parameter
You just need to put everything into an array first, Array.concat will accept an array or a single object:
var elements = [] .concat(words);
for (var i = 0; i 1b697c2705175b79da5fe06caf83bd62 CACTUS
printUpperCase(["cactus", " bear", "potato"]);
// => CACTUS
// BEAR
// POTATO21 - The difference between undefined and null
· null refers to a specific value, that is, "no value"
. JavaScript defaults to undefined for unassigned variables
· JavaScript will not set null values for unassigned variables. It is used by programmers to represent a worthless value
· Undefined is in json format data Invalid, while null is valid
· undefined type is undefined
· null is similar to object. Why?
· Both are primitive values
· Both are considered false(Boolean(undefined) // false, Boolean(null) // false).
· Identify whether the variable is undefined
· Check whether the variable is null
They are equal from the value point of view, but they are not equal from the type and value point of view
null === undefined // false##22 - Sort strings by non-ASCII characters
// ["cosas", "fútbol", "árbol", "único"] // Wrong sorting
// German
['Woche', ' wöchentlich', 'wäre', 'Wann'].sort();
// ["Wann", "Woche", "wäre", "wöchentlich"] // Wrong sorting
});
// [“á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"]
['Woche ', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare);
// ["Wann", "wäre", "Woche", "wöchentlich"]23 - Improving nested conditions
printBlackBackground();
} else if (color === ' red') {
printRedBackground();
} else if (color === 'blue') {
printBlueBackground();
} else if (color === 'green') {
printGreenBackground();
} else {
printYellowBackground();
}
}
case 'black':
printBlackBackground();
break;
case 'red':
printRedBackground( );
break;
case 'blue':
printBlueBackground();
break;
case 'green':
printGreenBackground();
break;
default:
printYellowBackground();
}
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;
}
var colorObj = {
'black': printBlackBackground,
'red': printRedBackground,
'blue': printBlueBackground,
'green': printGreenBackground,
'yellow': printYellowBackground
};
colorObjcolor;
}24 - ReactJs The keys of the child construction are very important
· Define the key in the parent component, not the child component
…
render() {
…
//Good
· Using arrays is not a good practice
· random() never executes
//Bad
· When the number of children is huge or contains complex components, use keys to improve Performance
· You must provide the key attribute for all children of ReactCSSTransitionGroup
25 - AngularJs: apply
建议:
· 给$apply传递函数表达式,这有一个错误处理机制,允许在消化周期中整合变化。
$scope.tip = ‘Javascript Tip’;
});
· 当25 - 在数组插入一个项
在数组的末尾添加一个元素很容易与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% 的速度
现在,如果我们正在尝试将一个项目添加到数组的开头:
arr.unshift(0);
[0].concat(arr); //在Chrome 47.0.2526.106 (Mac OS X 10.11.1)上提高了 98% 的速度
添加在阵列中的物品很容易使用splice,它是做它的最高效的方式。
?
1
2
items.splice(items.length / 2, 0, ‘hello’);
The above is the detailed content of Sharing some js tips. For more information, please follow other related articles on the PHP Chinese website!