From 47e33552d3074e682d1413ad5da3edde2f0615af Mon Sep 17 00:00:00 2001 From: fundon Date: Thu, 14 Jan 2016 11:43:18 +0800 Subject: [PATCH 01/27] zh_CN --- README-zh_CN.md | 579 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 579 insertions(+) create mode 100644 README-zh_CN.md diff --git a/README-zh_CN.md b/README-zh_CN.md new file mode 100644 index 00000000..f87c9b71 --- /dev/null +++ b/README-zh_CN.md @@ -0,0 +1,579 @@ +![header](https://raw.githubusercontent.com/loverajoel/jstips/master/resources/jstips-header-blog.gif) + +# Introducing Javascript Tips +> New year, new project. **A JS tip per day!** + +With great excitement, I introduce these short and useful daily Javascript tips that will allow you to improve your code writing. With less than 2 minutes each day, you will be able to read about performance, conventions, hacks, interview questions and all the items that the future of this awesome language holds for us. + +At midday, no matter if it is a weekend or a holiday, a tip will be posted and tweeted. + +### Can you help us enrich it? +Please feel free to send us a PR with your own Javascript tip to be published here. +Any improvements or suggestions are more than welcome! +[Click to see the instructions](https://github.com/loverajoel/jstips/blob/master/CONTRIBUTING.md) + +### Let’s keep in touch +To get updates, watch the repo and follow the [Twitter account](https://twitter.com/tips_js), only one tweet will be sent per day. It is a deal! +> Don't forget to Star the repo, as this will help to promote the project! + +# Tips list + +## #13 - Tip to measure performance of a javascript block + +2016-01-13 by [@manmadareddy](https://twitter.com/manmadareddy) + +For quickly measuring performance of a javascript block, we can use the console functions like +[```console.time(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimelabel) and [```console.timeEnd(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimeendlabel) + +```javascript +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"); // Outputs: Array initialize: 0.711ms +``` + +More info: +[Console object](https://github.com/DeveloperToolsWG/console-object), +[Javascript benchmarking](https://mathiasbynens.be/notes/javascript-benchmarking) + +Demo: [jsfiddle](https://jsfiddle.net/meottb62/) - [codepen](http://codepen.io/anon/pen/JGJPoa) (outputs in browser console) + +## #12 - Pseudomentatory parameters in ES6 functions + +> 2016-01-12 by [Avraam Mavridis](https://github.com/AvraamMavridis) + + +In many programming languages the parameters of a function is by default mandatory and the developer has to explicitly define that a parameter is optional. In Javascript every parameter is optional, but we can enforce this behavior without messing the actual body of a function taking advantage of the [**es6's default values for parameters**] (http://exploringjs.com/es6/ch_parameter-handling.html#sec_parameter-default-values) feature. + +```javascript +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` is a function that immediately throws an Error. If no value is passed for one of the parameters, the default value is gonna be used, `_err` will be called and an Error will be throwed. You can see more examples for the **default parameters feature** on [Mozilla's Developer Network ](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/default_parameters) + +## #11 - Hoisting +> 2016-01-11 by [@squizzleflip](https://twitter.com/squizzleflip) + +Understanding [hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) will help you organize your function scope. Just remember, variable declaration and function definition are hoisted to the top. Variable definition is not, even if you declare and define a variable on the same line. Also, variable **declaration** is letting the system know that the variable exists while **definition** is assigning it a value. + +```javascript +function doTheThing() { + // ReferenceError: notDeclared is not defined + console.log(notDeclared); + + // Outputs: undefined + console.log(definedLater); + var definedLater; + + definedLater = 'I am defined!' + // Outputs: 'I am defined!' + console.log(definedLater) + + // Outputs: undefined + console.log(definedSimulateneously); + var definedSimulateneously = 'I am defined!' + // Outputs: 'I am defined!' + console.log(definedSimulateneously) + + // Outputs: 'I did it!' + doSomethingElse(); + + function doSomethingElse(){ + console.log('I did it!'); + } + + // TypeError: undefined is not a function + functionVar(); + + var functionVar = function(){ + console.log('I did it!'); + } +} +``` + +To make things easier to read, declare all of your variables at the top of your function scope so it is clear which scope the variables are coming from. Define your variables before you need to use them. Define your functions at the bottom of your scope to keep them out of your way. + +## #10 - Check if a property is in a Object + +> 2016-01-10 by [@loverajoel](https://www.twitter.com/loverajoel) + +When you have to check if a property is present of an [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects), you probably are doing something like this: + +```javascript +var myObject = { + name: '@tips_js' +}; + +if (myObject['name']) { ... } + +``` + +Thats ok, but you have to know that there are two native ways for this kind of thing, the [`in` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in) and [`Object.hasOwnProperty`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), every object descended from `Object`, has available both ways. + +### See the big Difference + +```javascript +var myObject = { + name: '@tips_js' +}; + +myObject.hasOwnProperty('name'); // true +'name' in myObject; // true + +myObject.hasOwnProperty('valueOf'); // false, valueOf is inherited from the prototype chain +'valueOf' in myObject; // true + +``` + +Both differs in the depth how check the properties, in other words `hasOwnProperty` will only return true if key is available on that object directly, however `in` operator doesn't discriminate between properties created on an object and properties inherited from the prototype chain. + +Here another example + +```javascript +var myFunc = function() { + this.name = '@tips_js'; +}; +myFunc.prototype.age = '10 days'; + +var user = new myFunc(); + +user.hasOwnProperty('name'); // true +user.hasOwnProperty('age'); // false, because age is from the prototype chain +``` + +Check here the [live examples](https://jsbin.com/tecoqa/edit?js,console)! + +Also recommends read [this discussion](https://github.com/loverajoel/jstips/issues/62) about common mistakes at checking properties' existence in objects + +## #09 - Template Strings + +> 2016-01-09 by [@JakeRawr](https://github.com/JakeRawr) + +As of ES6, JS now has template strings as an alternative to the classic end quotes strings. + +Ex: +Normal string +```javascript +var firstName = 'Jake'; +var lastName = 'Rawr'; +console.log('My name is ' + firstName + ' ' + lastName); +// My name is Jake Rawr +``` +Template String +```javascript +var firstName = 'Jake'; +var lastName = 'Rawr'; +console.log(`My name is ${firstName} ${lastName}`); +// My name is Jake Rawr +``` + +You can do Multi-line strings without `\n` and simple logic (ie 2+3) inside `${}` in Template String. + +You are also able to to modify the output of template strings using a function; they are called [Tagged template strings] +(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings#Tagged_template_strings) for example usages of tagged template strings. + +You may also want to [read](https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2) to understand template strings more + +## #08 - Converting a Node List to an Array + +> 2016-01-08 by [@Tevko](https://twitter.com/tevko) + +The `querySelectorAll` method returns an array-like object called a node list. These data structures are referred to as "Array-like", because they appear as an array, but can not be used with array methods like `map` and `foreach`. Here's a quick, safe, and reusable way to convert a node list into an Array of DOM elements: + +```javascript +const nodelist = document.querySelectorAll('div'); +const nodelistToArray = Array.apply(null, nodelist); + +//later on .. + +nodelistToArray.forEach(...); +nodelistToArray.map(...); +nodelistToArray.slice(...); + +//etc... +``` + +The `apply` method is used to pass an array of arguments to a function with a given `this` value. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) states that `apply` will take an array like object, which is exactly what `querySelectorAll` returns. Since we don't need to specify a value for `this` in the context of the function, we pass in `null` or `0`. The result is an actual array of DOM elements which contains all of the available array methods. + +Or if you are using ES2015 you can use the [spread operator `...`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) + +```js +const nodelist = [...document.querySelectorAll('div')]; // returns a real Array + +//later on .. + +nodelist.forEach(...); +nodelist.map(...); +nodelist.slice(...); + +//etc... +``` + +## #07 - "use strict" and get lazy + +> 2016-01-07 by [@nainslie](https://twitter.com/nat5an) + +Strict-mode JavaScript makes it easier for the developer to write "secure" JavaScript. + +By default, JavaScript allows the programmer to be pretty careless, for example, by not requiring us to declare our variables with "var" when we first introduce them. While this may seem like a convenience to the unseasoned developer, it's also the source of many errors when a variable name is misspelled or accidentally referred to out of its scope. + +Programmers like to make the computer do the boring stuff for us, and automatically check our work for mistakes. That's what the JavaScript "use strict" directive allows us to do, by turning our mistakes into JavaScript errors. + +We add this directive either by adding it at the top of a js file: + +```javascript +// Whole-script strict mode syntax +"use strict"; +var v = "Hi! I'm a strict mode script!"; +``` + +or inside a function: + +```javascript +function f() +{ + // Function-level strict mode syntax + '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."; } +``` + +By including this directive in a JavaScript file or function, we will direct the JavaScript engine to execute in strict mode which disables a bunch of behaviors that are usually undesirable in larger JavaScript projects. Among other things, strict mode changes the following behaviors: +* Variables can only be introduced when they are preceded with "var" +* Attempting to write to readonly properties generates a noisy error +* You have to call constructors with the "new" keyword +* "this" is not implicitly bound to the global object +* Very limited use of eval() allowed +* Protects you from using reserved words or future reserved words as variable names + +Strict mode is great for new projects, but can be challenging to introduce into older projects that don't already use it in most places. It also can be problematic if your build chain concatenates all your js files into one big file, as this may cause all files to execute in strict mode. + +It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. +Strict mode is supported in: +* Internet Explorer from version 10. +* Firefox from version 4. +* Chrome from version 13. +* Safari from version 5.1. +* Opera from version 12. + +[See MDN for a fuller description of strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). + +## #06 - Writing a single method for arrays or single elements + +> 2016-01-06 by [@mattfxyz](https://twitter.com/mattfxyz) + +Rather than writing separate methods to handle an array and a single element parameter, write your functions so they can handle both. This is similar to how some of jQuery's functions work (`css` will modify everything matched by the selector). + +You just have to concat everything into an array first. `Array.concat` will accept an array or a single element. + +```javascript +function printUpperCase(words) { + var elements = [].concat(words); + for (var i = 0; i < elements.length; i++) { + console.log(elements[i].toUpperCase()); + } +} +``` + +`printUpperCase` is now ready to accept a single node or an array of nodes as its parameter. + +```javascript +printUpperCase("cactus"); +// => CACTUS +printUpperCase(["cactus", "bear", "potato"]); +// => CACTUS +// BEAR +// POTATO +``` + +## #05 - Differences between `undefined` and `null` + +> 2016-01-05 by [@loverajoel](https://twitter.com/loverajoel) + +- `undefined` means a variable has not been declared, or has been declared but has not yet been assigned a value +- `null` is an assignment value that means "no value" +- Javascript sets unassigned variables with a default value of `undefined` +- Javascript never sets a value to `null`. It is used by programmers to indicate that a `var` has no value. +- `undefined` is not valid in JSON while `null` is +- `undefined` typeof is `undefined` +- `null` typeof is an `object` +- Both are primitives +- Both are [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) + (`Boolean(undefined) // false`, `Boolean(null) // false`) +- You can know if a variable is [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined) + + ```javascript + typeof variable === "undefined" +``` +- You can check if a variable is [null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null) + + ```javascript + variable === null +``` +- The **equality** operator considers them equal, but the **identity** doesn't + + ```javascript + null == undefined // true + + null === undefined // false +``` + +## #04 - Sorting strings with accented characters + +> 2016-01-04 by [@loverajoel](https://twitter.com/loverajoel) + +Javascript has a native method **[sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)** that allows sorting arrays. Doing a simple `array.sort()` will treat each array entry as a string and sort it alphabetically. Also you can provide your [own custom sorting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters) function. + +```javascript +['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); +// ["Buenos Aires", "Mumbai", "New York", "Shanghai"] +``` + +But when you try order an array of non ASCII characters like this `['é', 'a', 'ú', 'c']`, you will obtain a strange result `['c', 'e', 'á', 'ú']`. That happens because sort works only with english language. + +See the next example: + +```javascript +// Spanish +['único','árbol', 'cosas', 'fútbol'].sort(); +// ["cosas", "fútbol", "árbol", "único"] // bad order + +// German +['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); +// ["Wann", "Woche", "wäre", "wöchentlich"] // bad order +``` + +Fortunately, there are two ways to overcome this behavior [localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) and [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator) provided by ECMAScript Internationalization API. + +> Both methods have their own custom parameters in order to configure it to work adequately. + +### Using `localeCompare()` + +```javascript +['ú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"] +``` + +### Using `Intl.Collator()` + +```javascript +['ú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"] +``` + +- For each method you can customize the location. +- According to [Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance) Intl.Collator is faster when comparing large numbers of strings. + +So when you are working with arrays of strings in a language other than English, remember to use this method to avoid unexpected sorting. + +## #03 - Improve Nested Conditionals +> 2016-01-03 by [AlbertoFuente](https://github.com/AlbertoFuente) + +How can we improve and make more efficient nested `if` statement in javascript. + +```javascript +if (color) { + if (color === 'black') { + printBlackBackground(); + } else if (color === 'red') { + printRedBackground(); + } else if (color === 'blue') { + printBlueBackground(); + } else if (color === 'green') { + printGreenBackground(); + } else { + printYellowBackground(); + } +} +``` + +One way to improve the nested `if` statement would be using the `switch` statement. Although it is less verbose and is more ordered, It's not recommended to use it because it's so difficult to debug errors, here's [why](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals/). + +```javascript +switch(color) { + case 'black': + printBlackBackground(); + break; + case 'red': + printRedBackground(); + break; + case 'blue': + printBlueBackground(); + break; + case 'green': + printGreenBackground(); + break; + default: + printYellowBackground(); +} +``` + +But what if we have a conditional with several checks in each statement? In this case, if we like to do less verbose and more ordered, we can use the conditional `switch`. +If we pass `true` as parameter to the `switch` statement, It allows us to put a conditional in each case. + +```javascript +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 always avoid having several checks in every condition, avoiding use of `switch` as far as possible and take into account that the most efficient way to do this is through an `object`. + +```javascript +var colorObj = { + 'black': printBlackBackground, + 'red': printRedBackground, + 'blue': printBlueBackground, + 'green': printGreenBackground, + 'yellow': printYellowBackground +}; + +if (color && colorObj.hasOwnProperty(color)) { + colorObj[color](); +} +``` + +Here you can find more information about [this](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/). + +## #02 - ReactJs - Keys in children components are important + +> 2016-01-02 by [@loverajoel](https://twitter.com/loverajoel) + + +The [key](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children) is an attribute that you must pass to all components created dynamically from an array. It's unique and constant id that React use for identify each component in the DOM and know that it's a different component and not the same one. Using keys will ensure that the child component is preserved and not recreated and prevent that weird things happens. + +> Key is not really about performance, it's more about identity (which in turn leads to better performance). randomly assigned and changing values are not identity [Paul O’Shannessy](https://github.com/facebook/react/issues/1342#issuecomment-39230939) + +- Use an existing unique value of the object. +- Define the keys in the parent components, not in child components + + ```javascript + //bad + ... + render() { +
{{item.name}}
+ } + ... + + //good + + ``` +- [Using array index is a bad practice.](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318#.76co046o9) +- `random()` will not work + + ```javascript + //bad + + ``` + +- You can create your own unique id, be sure that the method be fast and attach it to your object. +- When the amount of child are big or involve expensive components, use keys has performance improvements. +- [You must provide the key attribute for all children of ReactCSSTransitionGroup.](http://docs.reactjs-china.com/react/docs/animation.html) + +## #1 - AngularJs: `$digest` vs `$apply` + +> 2016-01-01 by [@loverajoel](https://twitter.com/loverajoel) + +One of the most appreciated features of AngularJs is the two way data binding. In order to make this work AngularJs evaluates the changes between the model and the view through cycles(`$digest`). You need to understand this concept in order to understand how the framework works under the hood. + +Angular evaluates each watcher whenever one event is fired, this is the known `$digest` cycle. +Sometimes you have to force to run a new cycle manually and you must choose the correct option because this phase is one of the most influential in terms of performance. + +### `$apply` +This core method lets you to start the digestion cycle explicitly, that means that all watchers are checked, the entire application starts the `$digest loop`. Internally after execute an optional function parameter, call internally to `$rootScope.$digest();`. + +### `$digest` +In this case the `$digest` method starts the `$digest` cycle for the current scope and its children. You should notice that the parents scopes will not be checked + and not be affected. + +### Recommendations +- Use `$apply` or `$digest` only when browser DOM events have triggered outside of AngularJS. +- Pass a function expression to `$apply`, this have a error handling mechanism and allow integrate changes in the digest cycle + + ```javascript + $scope.$apply(() => { + $scope.tip = 'Javascript Tip'; + }); + ``` + +- If only needs update the current scope or its children use `$digest`, and prevent a new digest cycle for the whole application. The performance benefit it's self evident +- `$apply()` is hard process for the machine and can lead to performance issues when having a lot of binding. +- If you are using >AngularJS 1.2.X, use `$evalAsync` is a core method that will evaluate the expression during the current cycle or the next. This can improve your application's performance. + + +## #0 - Insert item inside an Array +> 2015-12-29 + +Inserting an item into an existing array is a daily common task. You can add elements to the end of an array using push, to the beginning using unshift, or the middle using splice. + +But those are known methods, doesn't mean there isn't a more performant way, here we go... + +Adding an element at the end of the array is easy with push(), but there is a way more performant. + +```javascript +var arr = [1,2,3,4,5]; + +arr.push(6); +arr[arr.length] = 6; // 43% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1 +``` +Both methods modify the original array. Don't believe me? Check the [jsperf](http://jsperf.com/push-item-inside-an-array) + +Now we are trying to add an item to the beginning of the array + +```javascript +var arr = [1,2,3,4,5]; + +arr.unshift(0); +[0].concat(arr); // 98% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1 +``` +Here is a little bit detail, unshift edits the original array, concat returns a new array. [jsperf](http://jsperf.com/unshift-item-inside-an-array) + +Adding items at the middle of an array is easy with splice and is the most performant way to do it. + +```javascript +var items = ['one', 'two', 'three', 'four']; +items.splice(items.length / 2, 0, 'hello'); +``` + +I tried to run these tests in various Browsers and OS and the results were similar. I hope these tips will be useful for you and encourage to perform your own tests! + +### License +[![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/) From 255128dea4db0ca054f8b9cd48390d0e126ff2e2 Mon Sep 17 00:00:00 2001 From: fundon Date: Thu, 14 Jan 2016 20:03:27 +0800 Subject: [PATCH 02/27] translate the title --- README-zh_CN.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README-zh_CN.md b/README-zh_CN.md index f87c9b71..84592308 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,7 +1,12 @@ ![header](https://raw.githubusercontent.com/loverajoel/jstips/master/resources/jstips-header-blog.gif) +<-- # Introducing Javascript Tips > New year, new project. **A JS tip per day!** +--> + +# JavaScript 贴士介绍 +> 新年,新项目。**每天一个 JS 贴士!** With great excitement, I introduce these short and useful daily Javascript tips that will allow you to improve your code writing. With less than 2 minutes each day, you will be able to read about performance, conventions, hacks, interview questions and all the items that the future of this awesome language holds for us. From 8659fdd5b27dc4811132715ead239b0605f1fa8b Mon Sep 17 00:00:00 2001 From: fundon Date: Thu, 14 Jan 2016 20:05:16 +0800 Subject: [PATCH 03/27] comment --- README-zh_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 84592308..2361741c 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,6 +1,6 @@ ![header](https://raw.githubusercontent.com/loverajoel/jstips/master/resources/jstips-header-blog.gif) -<-- + From a37d00fac7c8ce0dbd7bd8b02bbf8543a995a1c0 Mon Sep 17 00:00:00 2001 From: fundon Date: Thu, 14 Jan 2016 21:32:20 +0800 Subject: [PATCH 04/27] upodate --- README-zh_CN.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README-zh_CN.md b/README-zh_CN.md index 2361741c..1d3a90bc 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -21,7 +21,11 @@ Any improvements or suggestions are more than welcome! To get updates, watch the repo and follow the [Twitter account](https://twitter.com/tips_js), only one tweet will be sent per day. It is a deal! > Don't forget to Star the repo, as this will help to promote the project! + + +# 贴士列表 ## #13 - Tip to measure performance of a javascript block @@ -578,7 +582,11 @@ var items = ['one', 'two', 'three', 'four']; items.splice(items.length / 2, 0, 'hello'); ``` + + +我已经在许多浏览器和操作系统,试着去运行这些测试,并且它们的结果非常相似。我希望这些贴士(建议)对你有用,并鼓励进行自己的测试! ### License [![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/) From 47aef5fe1307d53d95dcceedf81d92672fd1b510 Mon Sep 17 00:00:00 2001 From: fundon Date: Sat, 16 Jan 2016 17:03:28 +0800 Subject: [PATCH 05/27] update 0 --- README-zh_CN.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 1d3a90bc..c8bf0a61 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -548,14 +548,29 @@ In this case the `$digest` method starts the `$digest` cycle for the current sco - If you are using >AngularJS 1.2.X, use `$evalAsync` is a core method that will evaluate the expression during the current cycle or the next. This can improve your application's performance. + + +## #0 - 插入一项元素到数组中 > 2015-12-29 + + +在已存在的数组中插入一项元素是一件日常任务。你可以使用 push +操作把元素添加到数组的末尾,使用 unshift 操作添加到开头,或者使用 splice +添加到中间。 + +但这些都是已知的方法,并不意味着没有性能更好的方式,我们开始吧…… + +push() 可以很容易地把一个元素添加到数组的末尾,但这里有个更高效的方式。 + ```javascript var arr = [1,2,3,4,5]; @@ -563,9 +578,11 @@ var arr = [1,2,3,4,5]; arr.push(6); arr[arr.length] = 6; // 43% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1 ``` + ```javascript var arr = [1,2,3,4,5]; @@ -586,7 +603,9 @@ items.splice(items.length / 2, 0, 'hello'); I tried to run these tests in various Browsers and OS and the results were similar. I hope these tips will be useful for you and encourage to perform your own tests! --> -我已经在许多浏览器和操作系统,试着去运行这些测试,并且它们的结果非常相似。我希望这些贴士(建议)对你有用,并鼓励进行自己的测试! +我已经在许多浏览器和操作系统,试着去运行这些测试,并且它们的结果非常相似。 + +我希望这些贴士(建议)对你有用,并鼓励进行自己的测试! ### License [![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/) From 5a726b055f6c9b148ddfe4e77de86e8a4d5a197a Mon Sep 17 00:00:00 2001 From: fundon Date: Mon, 18 Jan 2016 17:10:02 +0800 Subject: [PATCH 06/27] update No. 0 --- README-zh_CN.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README-zh_CN.md b/README-zh_CN.md index c8bf0a61..b1fb0e34 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -584,15 +584,26 @@ Both methods modify the original array. Don't believe me? Check the [jsperf](htt Now we are trying to add an item to the beginning of the array --> +这两个方法都修改了原始数组。不相信我?瞧这里 [jsperf](http://jsperf.com/push-item-inside-an-array)。 + +现在,我们试着把元素添加到数组的开头。 + ```javascript var arr = [1,2,3,4,5]; arr.unshift(0); [0].concat(arr); // 98% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1 ``` + + +这里有个小细节,unshift 对原始数组进行编辑,而 concat 返回一个新数组。[jsperf](http://jsperf.com/unshift-item-inside-an-array) + +使用 splice 可以很容易地把元素添加到数组的中间,而且这样做是最高效的。 + ```javascript var items = ['one', 'two', 'three', 'four']; From 10349441e922d485cef40970c3b92b717e2d0996 Mon Sep 17 00:00:00 2001 From: fundon Date: Mon, 18 Jan 2016 17:31:07 +0800 Subject: [PATCH 07/27] update No. 0 --- README-zh_CN.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index b1fb0e34..04d33e65 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -563,13 +563,13 @@ But those are known methods, doesn't mean there isn't a more performant way, her Adding an element at the end of the array is easy with push(), but there is a way more performant. --> -在已存在的数组中插入一项元素是一件日常任务。你可以使用 push -操作把元素添加到数组的末尾,使用 unshift 操作添加到开头,或者使用 splice +在已存在的数组中插入一项元素是一件日常任务。你可以使用 `push` +操作把元素添加到数组的末尾,使用 `unshift` 操作添加到开头,或者使用 `splice` 添加到中间。 但这些都是已知的方法,并不意味着没有性能更好的方式,我们开始吧…… -push() 可以很容易地把一个元素添加到数组的末尾,但这里有个更高效的方式。 +`push()` 可以很容易地把一个元素添加到数组的末尾,但这里有个更高效的方式。 ```javascript @@ -600,9 +600,9 @@ Here is a little bit detail, unshift edits the original array, concat returns a Adding items at the middle of an array is easy with splice and is the most performant way to do it. --> -这里有个小细节,unshift 对原始数组进行编辑,而 concat 返回一个新数组。[jsperf](http://jsperf.com/unshift-item-inside-an-array) +这里有个小细节,`unshift` 对原始数组进行编辑,而 `concat` 返回一个新数组。[jsperf](http://jsperf.com/unshift-item-inside-an-array) -使用 splice 可以很容易地把元素添加到数组的中间,而且这样做是最高效的。 +使用 `splice` 可以很容易地把元素添加到数组的中间,而且这样做是最高效的。 ```javascript From 026a6082b75ea756d2b5962624b3fc42991f481c Mon Sep 17 00:00:00 2001 From: sjfkai Date: Thu, 21 Jan 2016 17:07:22 +0800 Subject: [PATCH 08/27] add README-zh_CN.md --- README-zh_CN.md | 890 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 7 +- 2 files changed, 895 insertions(+), 2 deletions(-) create mode 100644 README-zh_CN.md diff --git a/README-zh_CN.md b/README-zh_CN.md new file mode 100644 index 00000000..9a870cea --- /dev/null +++ b/README-zh_CN.md @@ -0,0 +1,890 @@ +![header](https://raw.githubusercontent.com/sjfkai/jstips/master/resources/jstips-header-blog.gif) + +# 关于 JavaScript Tips [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) +> 新年, 新项目. **每天一条JS小知识!** + +怀着激动的心情, 我来介绍这些可以提高你的代码质量的短小但有用的Javascript小技巧. 每天花费不到两分钟, 你就可以了解到有关性能,习惯,hacks,面试问题以及这个超棒语言提给我们的所有东西. + +无论工作日或节假日,都将有一条小知识发布。 + +### 你能帮我们丰富它吗? + +请尽情将你们自己的JavaScript小知识向我们提交PR吧。我们欢迎任何意见和建议! +[点这里查看操作说明](https://github.com/sjfkai/jstips/blob/master/CONTRIBUTING.md) + +### 让我们保持联系 +想要获取更新, watch 本仓库并关注[Twitter 账户](https://twitter.com/tips_js),每天只有一条推文发布,这永远不会变! +> 不要忘了Star我们的仓库,这将帮助我们提高此项目! + +# 小知识列表 + +## #20 - 返回对象,使方法可以链式调用([原文](https://github.com/loverajoel/jstips#20---return-objects-to-enable-chaining-of-functions)) + +> 2016-01-20 by [@WakeskaterX](https://twitter.com/WakeStudio) + +在面向对象的Javascript中为对象建立一个方法时,返回当前对象可以让你在一条链上调用方法。 + +```js +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(); +``` + + +## #19 - 安全的字符串拼接([原文](https://github.com/loverajoel/jstips#19---safe-string-concatenation)) + +> 2016-01-19 by [@gogainda](https://twitter.com/gogainda) + +假如你需要拼接一些不确定类型的变量为字符串,你需要确保算术运算符在你拼接时不会起作用。 + +```javascript +var one = 1; +var two = 2; +var three = '3'; + +var result = ''.concat(one, two, three); //"123" +``` + +这应该就是你所期望的拼接结果。如果不这样,拼接时加号可能会导致你意想不到的结果: + +```javascript +var one = 1; +var two = 2; +var three = '3'; + +var result = one + two + three; //"33" instead of "123" +``` + +关于性能,与用[```join```](http://www.sitepoint.com/javascript-fast-string-concatenation/)来拼接字符串相比 ```concat```的效率是几乎一样的。 + +你可以在[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply)了解更多关于```concat```方法的内容。 + +## #18 - 更快的取整([原文](https://github.com/loverajoel/jstips#18---rounding-the-fast-way)) + +> 2016-01-18 by [pklinger](https://github.com/pklinger) + +今天的小知识有关性能表现。[曾经用过双波浪](http://stackoverflow.com/questions/5971645/what-is-the-double-tilde-operator-in-javascript) `~~` 操作符吗? 有时候也称为双非(NOT)位操作. 你可以用它作为`Math.floor()`的替代方法。为什么会这样呢? + +一个位操作符 `~` 将输入的32位的数字(input)转换为 `-(input+1)`. 两个位操作符将输入(input)转变为 `-(-(input + 1)+1)` 是一个使结果趋向于0的取整好工具. 对于数字, 负数就像使用`Math.ceil()`方法而正数就像使用`Math.floor()`方法. 转换失败时,返回`0`,这在`Math.floor()`方法转换失败返回`NaN`时或许会派上用场。 + +```javascript +// 单个 ~ +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 +``` + +虽然`~~`的性能更好,为了代码的可读性请用`Math.floor()`. + +## #17 - Node.js: 运行未被引用的模块([原文](https://github.com/loverajoel/jstips#17---nodejs-run-a-module-if-it-is-not-required)) + +> 2016-01-17 by [@odsdq](https://twitter.com/odsdq) + +在Node里,你可以让你的程序根据其运行自`require('./something.js')`或者`node something.js`而做不同的处理。如果你想与你的一个独立的模块进行交互,这是非常有用的。 + +```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; +} +``` + +更多内容请看 [modules的文档](https://nodejs.org/api/modules.html#modules_module_parent) + +## #16 - 向回调方法传递参数([原文](https://github.com/loverajoel/jstips#16---passing-arguments-to-callback-functions)) +> 2016-01-16 by [@minhazav](https://twitter.com/minhazav) + +通常下,你并不能给回调函数传递参数。 比如: +```js +function callback() { + console.log('Hi human'); +} + +document.getElementById('someelem').addEventListener('click', callback); +``` +你可以借助Javascript闭包的优势来传递参数给回调函数。看这个例子: +```js +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的文档](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures)。 + +这种方法使参数`x`和`y`在回调方法被调用时处于其作用域内。 + +另一个办法是使用`bind`方法。比如: +```js +var alertText = function(text) { + alert(text); +}; + +document.getElementById('someelem').addEventListener('click', alertText.bind(this, 'hello')); +``` +两种方法之间有着微小的性能差异,请看[jsperf](http://jsperf.com/bind-vs-closure-23). + +## #15 - 更简单的使用indexOf实现contains功能([原文](https://github.com/loverajoel/jstips#15---even-simpler-way-of-using-indexof-as-a-contains-clause)) +> 2016-01-15 by [@jhogoforbroke](https://twitter.com/jhogoforbroke) + +JavaScript并未提供contains方法。检测子字符串是否存在于字符串或者变量是否存在于数组你可能会这样做: + +```javascript +var someText = 'javascript rules'; +if (someText.indexOf('javascript') !== -1) { +} + +// or +if (someText.indexOf('javascript') >= 0) { +} +``` + +但是让我们看一下这些 [Expressjs](https://github.com/strongloop/express)代码段。 + +[examples/mvc/lib/boot.js](https://github.com/strongloop/express/blob/2f8ac6726fa20ab5b4a05c112c886752868ac8ce/examples/mvc/lib/boot.js#L26) +```javascript +for (var key in obj) { + // "reserved" exports + if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue; +``` + +[lib/utils.js](https://github.com/strongloop/express/blob/2f8ac6726fa20ab5b4a05c112c886752868ac8ce/lib/utils.js#L93) +```javascript +exports.normalizeType = function(type){ + return ~type.indexOf('/') + ? acceptParams(type) + : { value: mime.lookup(type), params: {} }; +}; +``` + +[examples/web-service/index.js](https://github.com/strongloop/express/blob/2f8ac6726fa20ab5b4a05c112c886752868ac8ce/examples/web-service/index.js#L35) +```javascript +// key is invalid +if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key')); +``` + +难点是 [位操作符](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) **~**, “按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。” + +它将`-1`转换为`0`,而`0`在javascript为`false`,所以: + +```javascript +var someText = 'text'; +!!~someText.indexOf('tex'); // someText contains "tex" - true +!~someText.indexOf('tex'); // someText NOT contains "tex" - false +~someText.indexOf('asd'); // someText doesn't contain "asd" - false +~someText.indexOf('ext'); // someText contains "ext" - true +``` + +### String.prototype.includes() + +在ES6中提供了[includes() 方法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/includes)供我们判断一个字符串是否包含了另一个字符串: + +```javascript +'something'.includes('thing'); // true +``` + +在ECMAScript 2016 (ES7)甚至可能将其应用于数组,像indexOf一样: + +```javascript +!!~[1, 2, 3].indexOf(1); // true +[1, 2, 3].includes(1); // true +``` + +**不幸的是, 只有Chrome、Firefox、Safari 9及其更高版本和Edge支持了这功能。IE11及其更低版本并不支持** +**最好在受控的环境中使用此功能** + +## #14 - 箭头函数 #ES6([原文](https://github.com/loverajoel/jstips#14---fat-arrow-functions-es6)) +> 2016-01-13 by [@pklinger](https://github.com/pklinger/) + +介绍一个ES6的新特性,箭头函数或许一个让你用更少行写更多代码的方便工具。它的名字(fat arrow functions)来自于它的语法`=>`是一个比瘦箭头`->`要'胖的箭头'(译者注:但是国内貌似不分胖瘦就叫箭头函数)。Some programmers might already know this type of functions from different languages such as Haskell as 'lambda expressions' respectively 'anonymous functions'. It is called anonymous, as these arrow functions do not have a descriptive function name.(译者注:一些其他语言中的箭头函数,避免不准确就不翻译了 欢迎PR) + +### 有什么益处呢? +* 语法: 更少的代码行; 不再需要一遍一遍的打`function`了 +* 语义: 从上下文中捕获`this`关键字 + +### 简单的语法示例 +观察一下这两个功能完全相同的代码片段。你将很快明白箭头函数做了什么。 + +```javascript +// 箭头函数的一般语法 +param => expression + +// 也可以用用小括号 +// 多参数时小括号是必须的 +(param1 [, param2]) => expression + + +// 使用functions +var arr = [5,3,2,9,1]; +var arrFunc = arr.map(function(x) { + return x * x; +}); +console.log(arr) + +// 使用箭头函数 +var arr = [5,3,2,9,1]; +var arrFunc = arr.map((x) => x*x); +console.log(arr) +``` + +正如你所看到的,箭头函数在这种情况下省去了写小括号,function以及return的时间。我建议你总是使用小括号,因为对于像`(x,y) => x+y`这样多参数函数,小括号总是需要的。这仅是以防在不同使用场景下忘记小括号的一种方法。但是上面的代码和`x => x*x`是一样的。至此仅是语法上的提升,减少了代码行数并提高了可读性。 + +### Lexically binding `this` + +这是另一个使用箭头函数的好原因。这是一个关于`this`上下文的问题。使用箭头函数,你不需要再担心`.bind(this)`也不用再设置`that = this`了,因为箭头函数继承了外围作用域的`this`值。看一下下面的[示例](https://jsfiddle.net/pklinger/rw94oc11/): + +```javascript + +// 全局定义 this.i +this.i = 100; + +var counterA = new CounterA(); +var counterB = new CounterB(); +var counterC = new CounterC(); +var counterD = new CounterD(); + +// 不好的例子 +function CounterA() { + // CounterA的`this`实例 (!!调用时忽略了此实例) + this.i = 0; + setInterval(function () { + // `this` 指向全局(global)对象,而不是CounterA的`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); +} + +// 箭头函数 +function CounterD() { + this.i = 0; + setInterval(() => { + this.i++; + document.getElementById("counterD").innerHTML = this.i; + }, 500); +} +``` + +更多有关箭头函数的内容可以查看[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)。更多语法选项请看[这里](http://jsrocks.org/2014/10/arrow-functions-and-their-scope/). + + +## #13 - 测量javascript代码块性能的小知识([原文](https://github.com/loverajoel/jstips#13---tip-to-measure-performance-of-a-javascript-block)) + +> 2016-01-13 by [@manmadareddy](https://twitter.com/manmadareddy) + +快速的测量javascript的性能,我们可以使用console的方法,例如 +[```console.time(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimelabel) 和 [```console.timeEnd(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimeendlabel) + +```javascript +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"); // Outputs: Array initialize: 0.711ms +``` + +更多内容: +[Console object](https://github.com/DeveloperToolsWG/console-object), +[Javascript benchmarking](https://mathiasbynens.be/notes/javascript-benchmarking) + +Demo: [jsfiddle](https://jsfiddle.net/meottb62/) - [codepen](http://codepen.io/anon/pen/JGJPoa) (在浏览器控制台输出) + + +## #12 - ES6中的伪强制参数 #ES6([原文](https://github.com/loverajoel/jstips#12---pseudomandatory-parameters-in-es6-functions-es6)) + +> 2016-01-12 by [Avraam Mavridis](https://github.com/AvraamMavridis) + + +在许多编程语言中,方法的参数时默认强制需要的,开发人员需要明确定义一个可选的参数。在Javascript中任何参数都是可选的,但是我们可以利用[**es6参数默认值**](http://exploringjs.com/es6/ch_parameter-handling.html#sec_parameter-default-values)特性的优点来实现强制要求这种表现而不污染本身的函数体。 + +```javascript +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`方法将被调用而错误也将被抛出。你可以从[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Default_parameters)看到更多关于**默认参数特性**的例子。 + + +## #11 - 变量提升([原文](https://github.com/loverajoel/jstips#11---hoisting)) +> 2016-01-11 by [@squizzleflip](https://twitter.com/squizzleflip) + +了解[变量提升](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var#var_hoisting)可以帮助你组织方法作用域。只要记住变量生命和方法生命都会被提升到顶部。变量的定义不会提升,即使你在同一行声明和定义一个变量。变量**声明**是让系统知道有这个变量存在而**定义**是给其赋值。 + +```javascript +function doTheThing() { + // ReferenceError: notDeclared is not defined + console.log(notDeclared); + + // Outputs: undefined + console.log(definedLater); + var definedLater; + + definedLater = 'I am defined!' + // Outputs: 'I am defined!' + console.log(definedLater) + + // Outputs: undefined + console.log(definedSimulateneously); + var definedSimulateneously = 'I am defined!' + // Outputs: 'I am defined!' + console.log(definedSimulateneously) + + // Outputs: 'I did it!' + doSomethingElse(); + + function doSomethingElse(){ + console.log('I did it!'); + } + + // TypeError: undefined is not a function + functionVar(); + + var functionVar = function(){ + console.log('I did it!'); + } +} +``` + +为了让你的代码更易读,将所有的变量声明在函数的顶端,这样可以更清楚的知道变量来自哪个作用域。在使用变量之前声明变量。将方法定义在函数的底部。 + +## #10 - 检查某对象是否有某属性([原文](https://github.com/loverajoel/jstips#10---check-if-a-property-is-in-a-object)) + +> 2016-01-10 by [@loverajoel](https://www.twitter.com/loverajoel) + +当你需要检查某属性是否存在于一个[对象](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects),你可能会这样做: + +```javascript +var myObject = { + name: '@tips_js' +}; + +if (myObject.name) { ... } + +``` + +这是可以的,但是你需要知道有两种原生方法可以解决此类问题。[`in` 操作符](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/in) 和 [`Object.hasOwnProperty`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty),任何继承自`Object`的对象都可以使用这两种方法。 + +### 看一下较大的区别 + +```javascript +var myObject = { + name: '@tips_js' +}; + +myObject.hasOwnProperty('name'); // true +'name' in myObject; // true + +myObject.hasOwnProperty('valueOf'); // false, valueOf 继承自原型链 +'valueOf' in myObject; // true + +``` + +两者检查属性的深度不同,换言之`hasOwnProperty`只在本身有此属性时返回true,而`in`操作符不区分属性来自于本身或继承自原型链。 + +这是另一个例子 + +```javascript +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来自于原型链 +``` + +[在线示例](https://jsbin.com/tecoqa/edit?js,console)! + +同样建议阅读关于检查对象是否包含属性时常见错误的[讨论](https://github.com/loverajoel/jstips/issues/62)。 + +## #09 - 模板字符串 + +> 2016-01-09 by [@JakeRawr](https://github.com/JakeRawr)([原文](https://github.com/loverajoel/jstips#09---template-strings)) + +ES6中,JS现在有了引号拼接字符串的替代品,模板字符串。 + +示例: +普通字符串 +```javascript +var firstName = 'Jake'; +var lastName = 'Rawr'; +console.log('My name is ' + firstName + ' ' + lastName); +// My name is Jake Rawr +``` +模板字符串 +```javascript +var firstName = 'Jake'; +var lastName = 'Rawr'; +console.log(`My name is ${firstName} ${lastName}`); +// My name is Jake Rawr +``` + +在模板字符串中,你可以不用`\n`来生成多行字符串还可以在`${}`里做简单的逻辑运算(例如 2+3)。 + +你也可以使用方法修改模板字符串的输出内容;他们被称为[带标签的模板字符串](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings#Tagged_template_strings)(其中有带标签的模板字符串的示例) + +或许你还想[阅读更多内容](https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2)来了解模板字符串。 + +## #08 - 将Node List转换为数组(Array)([原文](https://github.com/loverajoel/jstips#08---converting-a-node-list-to-an-array)) + +> 2016-01-08 by [@Tevko](https://twitter.com/tevko) + +`querySelectorAll`方法返回一个类数组对象称为node list。这些数据结构被称为“类数组”,因为他们看似数组却没有类似`map`、`foreach`这样的数组方法。这是一个快速、安全、可重用的方法将node list转换为DOM元素的数组: + +```javascript +const nodelist = document.querySelectorAll('div'); +const nodelistToArray = Array.apply(null, nodelist); + +//之后 .. + +nodelistToArray.forEach(...); +nodelistToArray.map(...); +nodelistToArray.slice(...); + +//等... +``` + +`apply`方法可以在指定`this`时以数组形式向方法传递参数。[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply)规定`apply`可以接受类数组对象,恰巧就是`querySelectorAll`方法所返回的内容。如果我们不需要指定方法内`this`的值传`null`或`0`即可。返回的结果即包含所有数组方法的DOM元素数组。 + +如果你正在用ES2015你可以使用[展开运算符 `...`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_operator) + +```js +const nodelist = [...document.querySelectorAll('div')]; // 返回一个真正的数组 + +//之后 .. + +nodelist.forEach(...); +nodelist.map(...); +nodelist.slice(...); + +//等... +``` + +## #07 - "use strict" 变得懒惰([原文](https://github.com/loverajoel/jstips#07---use-strict-and-get-lazy)) + +> 2016-01-07 by [@nainslie](https://twitter.com/nat5an) + +(译者注:此片翻译较渣,欢迎指正,建议大家[阅读原文](https://github.com/loverajoel/jstips#07---use-strict-and-get-lazy)或直接阅读[MDN对严格模式的中文介绍](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode) 并欢迎PR) + +JavaScript的严格模式使开发者更容易写出“安全”的代码。 + +通常情况下,JavaScript允许程序员相当粗心,比如你可以引用一个从未用"var"声明的变量。或许对于一个刚入门的开发者来说这看起来很方便,但这也是变量拼写错误或者从作用域外引用变量时引发的一系列错误的原因。 + +程序员喜欢电脑帮我们做一些无聊的工作,喜欢它自动的检查我们工作上的错误。这就是"use strict"帮我们做的,它把我们的错误转变为了JavaScript错误。 + +我们把这个指令放在js文件顶端来使用它: + +```javascript +// 全脚本严格模式 +"use strict"; +var v = "Hi! I'm a strict mode script!"; +``` + +或者放在一个方法内: + +```javascript +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引擎运行在严格模式下,这直接禁止了许多大项目中不受欢迎的操作。另外,严格模式也改变了以下行为: +* 只有被"var"声明过的变量才可以引用。 +* 试图写只读变量时将会报错 +* 只能通过"new"关键字调用构造方法 +* "this"不再隐式的指向全局变量 +* 对eval()有更严格的限制 +* 防止你使用预保留关键字命名变量 + +严格模式对于新项目来说是很棒的,但对于一些并没有使用它的老项目来说,引入它也是很有挑战性的。如果你把所有js文件都连接到一个大文件中的话,可能导致所有文件都运行在严格模式下,这可能也会有一些问题。 + +It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. +严格模式的支持情况: +* Internet Explorer from version 10. +* Firefox from version 4. +* Chrome from version 13. +* Safari from version 5.1. +* Opera from version 12. + +[MDN对严格模式的全面介绍](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode) + +## #06 - 可以接受单各参数和数组的方法 + +> 2016-01-06 by [@mattfxyz](https://twitter.com/mattfxyz)([原文](https://github.com/loverajoel/jstips#06---writing-a-single-method-for-arrays-or-single-elements)) + +写一个方法可以接受单个参数也可以接受一个数组,而不是分开写两个方法。这和jQuery的一些方法的工作原理很像(`css` 可以修改任何匹配到的选择器). + +你只要把任何东西连接到一个数组. `Array.concat`可以接受一个数组也可以接受单个参数。 + +```javascript +function printUpperCase(words) { + var elements = [].concat(words); + for (var i = 0; i < elements.length; i++) { + console.log(elements[i].toUpperCase()); + } +} +``` + +`printUpperCase`现在可以接受单个单词或多个单词的数组作为它的参数。 + +```javascript +printUpperCase("cactus"); +// => CACTUS +printUpperCase(["cactus", "bear", "potato"]); +// => CACTUS +// BEAR +// POTATO +``` + +## #05 - `undefined`与`null`的区别([原文](https://github.com/loverajoel/jstips#05---differences-between-undefined-and-null)) + +> 2016-01-05 by [@loverajoel](https://twitter.com/loverajoel) + +- `undefined`表示一个变量没有被声明,或者被声明了但没有被赋值 +- `null`是一个表示“没有值”的值 +- Javascript将未赋值的变量默认值设为`undefined` +- Javascript从来不会将变量设为`null`。它是用来让程序员表明某个用`var`声明的变量时没有值的。 +- `undefined`不是一个有效的JSON而`null`是 +- `undefined`的类型(typeof)是`undefined` +- `null`的类型(typeof)是`object`. [为什么?](http://www.2ality.com/2013/10/typeof-null.html) +- 它们都是基本来兴 +- 他们都是[falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) + (`Boolean(undefined) // false`, `Boolean(null) // false`) +- 你可以这样判断一个变量是否是[undefined](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined) + + ```javascript + typeof variable === "undefined" +``` +- 你可以这样判断一个变量是否是[null](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/null) + + ```javascript + variable === null +``` +- **双等号**比较时它们相等,但**三等号**比较时不相等 + + ```javascript + null == undefined // true + + null === undefined // false +``` + +## #04 - 排列带音节字母的字符串([原文](https://github.com/loverajoel/jstips#04---sorting-strings-with-accented-characters)) + +> 2016-01-04 by [@loverajoel](https://twitter.com/loverajoel) + +Javascript有一个原生方法**[sort](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)**可以排列数组。一次简单的`array.sort()`将每一个数组元素视为字符串并按照字母表排列。你也可以提供[自定义排列方法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters) function. + +```javascript +['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); +// ["Buenos Aires", "Mumbai", "New York", "Shanghai"] +``` + +但是当你试图整理一个如`['é', 'a', 'ú', 'c']`这样的非ASCII元素的数组时,你可能会得到一个奇怪的结果`['c', 'e', 'á', 'ú']`。这是因为排序方法只在英文下有用。 + +看一下下一个例子: + +```javascript +// 西班牙语 +['único','árbol', 'cosas', 'fútbol'].sort(); +// ["cosas", "fútbol", "árbol", "único"] // bad order + +// 德语 +['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); +// ["Wann", "Woche", "wäre", "wöchentlich"] // bad order +``` + +幸运的是,有两种方法可以解决这个问题,由ECMAScript国际化API提供的[localeCompare](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)和[Intl.Collator](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Collator)。 + +> 两个方法都有自定义配置参数可以使其更好用。 + +### 使用`localeCompare()` + +```javascript +['ú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()` + +```javascript +['ú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"] +``` + +- 两个方法都可以自定义区域位置。For each method you can customize the location. +- 根据[Firefox](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance),当比较大数量的字符串是Intl.Collator更快。 + +所以当你处理一个由非英语组成的字符串数组时,记得使用此方法来避免排序出现意外。 + +## #03 - 优化嵌套的条件语句([原文](https://github.com/loverajoel/jstips#03---improve-nested-conditionals)) +> 2016-01-03 by [AlbertoFuente](https://github.com/AlbertoFuente) + +我们怎样来提高和优化javascript里嵌套的`if`语句呢? + +```javascript +if (color) { + if (color === 'black') { + printBlackBackground(); + } else if (color === 'red') { + printRedBackground(); + } else if (color === 'blue') { + printBlueBackground(); + } else if (color === 'green') { + printGreenBackground(); + } else { + printYellowBackground(); + } +} +``` + +一种方法来提高嵌套的`if`语句是用`switch`语句。虽然它不那么啰嗦而且排列整齐,但是并不建议使用它,因为这对于调试错误很困难。这告诉你[为什么](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals/). + +```javascript +switch(color) { + case 'black': + printBlackBackground(); + break; + case 'red': + printRedBackground(); + break; + case 'blue': + printBlueBackground(); + break; + case 'green': + printGreenBackground(); + break; + default: + printYellowBackground(); +} +``` + +但是如果在每个语句中都有很多条件检查时该怎么办呢?这种情况下,如果我们想要不罗嗦又整洁的话,我们可以用有条件的`switch`。如果我们传递`true`给`switch`语句,我没变可以在每个case中使用条件语句了。 + +```javascript +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`。 + +```javascript +var colorObj = { + 'black': printBlackBackground, + 'red': printRedBackground, + 'blue': printBlueBackground, + 'green': printGreenBackground, + 'yellow': printYellowBackground +}; + +if (color in colorObj) { + colorObj[color](); +} +``` + +这里有更多相关的[内容](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/). + +## #02 - ReactJs - Keys in children components are important([原文](https://github.com/loverajoel/jstips#02---reactjs---keys-in-children-components-are-important)) + +(译者注:本人对ReactJs了解不多,就不翻译了,免得误导大家 欢迎PR) + +> 2016-01-02 by [@loverajoel](https://twitter.com/loverajoel) + + +The [key](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children) is an attribute that you must pass to all components created dynamically from an array. It's unique and constant id that React use for identify each component in the DOM and know that it's a different component and not the same one. Using keys will ensure that the child component is preserved and not recreated and prevent that weird things happens. + +> Key is not really about performance, it's more about identity (which in turn leads to better performance). randomly assigned and changing values are not identity [Paul O’Shannessy](https://github.com/facebook/react/issues/1342#issuecomment-39230939) + +- Use an existing unique value of the object. +- Define the keys in the parent components, not in child components + + ```javascript + //bad + ... + render() { +
{{item.name}}
+ } + ... + + //good + + ``` +- [Using array index is a bad practice.](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318#.76co046o9) +- `random()` will not work + + ```javascript + //bad + + ``` + +- You can create your own unique id, be sure that the method be fast and attach it to your object. +- When the amount of child are big or involve expensive components, use keys has performance improvements. +- [You must provide the key attribute for all children of ReactCSSTransitionGroup.](http://docs.reactjs-china.com/react/docs/animation.html) + +## #1 - AngularJs: `$digest` vs `$apply`([原文](https://github.com/loverajoel/jstips#1---angularjs-digest-vs-apply)) + +(译者注:本人对AngularJs了解不多,就不翻译了,免得误导大家 欢迎PR) + +> 2016-01-01 by [@loverajoel](https://twitter.com/loverajoel) + +One of the most appreciated features of AngularJs is the two way data binding. In order to make this work AngularJs evaluates the changes between the model and the view through cycles(`$digest`). You need to understand this concept in order to understand how the framework works under the hood. + +Angular evaluates each watcher whenever one event is fired, this is the known `$digest` cycle. +Sometimes you have to force to run a new cycle manually and you must choose the correct option because this phase is one of the most influential in terms of performance. + +### `$apply` +This core method lets you to start the digestion cycle explicitly, that means that all watchers are checked, the entire application starts the `$digest loop`. Internally after execute an optional function parameter, call internally to `$rootScope.$digest();`. + +### `$digest` +In this case the `$digest` method starts the `$digest` cycle for the current scope and its children. You should notice that the parents scopes will not be checked + and not be affected. + +### Recommendations +- Use `$apply` or `$digest` only when browser DOM events have triggered outside of AngularJS. +- Pass a function expression to `$apply`, this have a error handling mechanism and allow integrate changes in the digest cycle + + ```javascript + $scope.$apply(() => { + $scope.tip = 'Javascript Tip'; + }); + ``` + +- If only needs update the current scope or its children use `$digest`, and prevent a new digest cycle for the whole application. The performance benefit it's self evident +- `$apply()` is hard process for the machine and can lead to performance issues when having a lot of binding. +- If you are using >AngularJS 1.2.X, use `$evalAsync` is a core method that will evaluate the expression during the current cycle or the next. This can improve your application's performance. + + +## #0 - 向数组中插入元素([原文](https://github.com/loverajoel/jstips#0---insert-item-inside-an-array)) +> 2015-12-29 + +向一个数组中插入元素是平时很常见的一件事情。你可以使用push在数组尾部插入元素,可以用unshift在数组头部插入元素,也可以用splice在数组中间插入元素。 + +但是这些已知的方法,并不意味着没有更加高效的方法。让我们接着往下看…… + +向数组结尾添加元素用push()很简单,但下面有一个更高效的方法 + +```javascript +var arr = [1,2,3,4,5]; + +arr.push(6); +arr[arr.length] = 6; // 在Mac OS X 10.11.1下的Chrome 47.0.2526.106中快43% +``` +两种方法都是修改原始数组。不信?看看[jsperf](http://jsperf.com/push-item-inside-an-array) + +现在我们试着向数组的头部添加元素: + +```javascript +var arr = [1,2,3,4,5]; + +arr.unshift(0); +[0].concat(arr); // 在Mac OS X 10.11.1下的Chrome 47.0.2526.106中快98% +``` +这里有一些小区别,unshift操作的是原始数组,concat返回一个新数组,参考[jsperf](http://jsperf.com/unshift-item-inside-an-array) + +使用splice可以简单的向数组总监添加元素,这也是最高效的方法。 + +```javascript +var items = ['one', 'two', 'three', 'four']; +items.splice(items.length / 2, 0, 'hello'); +``` + +我在许多浏览器和系统中进行了测试,结果都是相似的。希望这条小知识可以帮到你,也欢迎大家自行测试。 + +### License +[![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/) diff --git a/README.md b/README.md index 23761343..8e81ab76 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![header](https://raw.githubusercontent.com/loverajoel/jstips/master/resources/jstips-header-blog.gif) +![header](https://raw.githubusercontent.com/sjfkai/jstips/master/resources/jstips-header-blog.gif) # Introducing JavaScript Tips [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) > New year, new project. **A JS tip per day!** @@ -10,12 +10,15 @@ At midday, no matter if it is a weekend or a holiday, a tip will be posted and t ### Can you help us enrich it? Please feel free to send us a PR with your own JavaScript tip to be published here. Any improvements or suggestions are more than welcome! -[Click to see the instructions](https://github.com/loverajoel/jstips/blob/master/CONTRIBUTING.md) +[Click to see the instructions](https://github.com/sjfkai/jstips/blob/master/CONTRIBUTING.md) ### Let’s keep in touch To get updates, watch the repo and follow the [Twitter account](https://twitter.com/tips_js), only one tweet will be sent per day. It is a deal! > Don't forget to Star the repo, as this will help to promote the project! +### Other language +[简体中文(simplified Chinese)](https://github.com/sjfkai/jstips/blob/master/README-zh_CN.md) + # Tips list ## #20 - Return objects to enable chaining of functions From 3ca6b488d5904f9bb25230fda08fbe074ba169b1 Mon Sep 17 00:00:00 2001 From: sjfkai Date: Thu, 21 Jan 2016 17:19:15 +0800 Subject: [PATCH 09/27] changed link to the original repo --- README-zh_CN.md | 4 ++-- README.md | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 9a870cea..9704bfa5 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,4 +1,4 @@ -![header](https://raw.githubusercontent.com/sjfkai/jstips/master/resources/jstips-header-blog.gif) +![header](https://raw.githubusercontent.com/loverajoel/jstips/master/resources/jstips-header-blog.gif) # 关于 JavaScript Tips [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) > 新年, 新项目. **每天一条JS小知识!** @@ -10,7 +10,7 @@ ### 你能帮我们丰富它吗? 请尽情将你们自己的JavaScript小知识向我们提交PR吧。我们欢迎任何意见和建议! -[点这里查看操作说明](https://github.com/sjfkai/jstips/blob/master/CONTRIBUTING.md) +[点这里查看操作说明](https://github.com/loverajoel/jstips/blob/master/CONTRIBUTING.md) ### 让我们保持联系 想要获取更新, watch 本仓库并关注[Twitter 账户](https://twitter.com/tips_js),每天只有一条推文发布,这永远不会变! diff --git a/README.md b/README.md index 8e81ab76..6affc9e7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![header](https://raw.githubusercontent.com/sjfkai/jstips/master/resources/jstips-header-blog.gif) +![header](https://raw.githubusercontent.com/loverajoel/jstips/master/resources/jstips-header-blog.gif) # Introducing JavaScript Tips [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) > New year, new project. **A JS tip per day!** @@ -10,14 +10,15 @@ At midday, no matter if it is a weekend or a holiday, a tip will be posted and t ### Can you help us enrich it? Please feel free to send us a PR with your own JavaScript tip to be published here. Any improvements or suggestions are more than welcome! -[Click to see the instructions](https://github.com/sjfkai/jstips/blob/master/CONTRIBUTING.md) +[Click to see the instructions](https://github.com/loverajoel/jstips/blob/master/CONTRIBUTING.md) ### Let’s keep in touch To get updates, watch the repo and follow the [Twitter account](https://twitter.com/tips_js), only one tweet will be sent per day. It is a deal! > Don't forget to Star the repo, as this will help to promote the project! +var entry = require('./../../dev/webpack/entry'); ### Other language -[简体中文(simplified Chinese)](https://github.com/sjfkai/jstips/blob/master/README-zh_CN.md) +[简体中文(simplified Chinese)](https://github.com/loverajoel/jstips/blob/master/README-zh_CN.md) # Tips list ## #20 - Return objects to enable chaining of functions From 7eb2e755ae99113b13ecf51a4a148a50d697ba9f Mon Sep 17 00:00:00 2001 From: sjfkai Date: Thu, 21 Jan 2016 17:24:55 +0800 Subject: [PATCH 10/27] fix careless mistake --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 6affc9e7..fca37973 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ Any improvements or suggestions are more than welcome! To get updates, watch the repo and follow the [Twitter account](https://twitter.com/tips_js), only one tweet will be sent per day. It is a deal! > Don't forget to Star the repo, as this will help to promote the project! -var entry = require('./../../dev/webpack/entry'); ### Other language [简体中文(simplified Chinese)](https://github.com/loverajoel/jstips/blob/master/README-zh_CN.md) From 004a15be8957f9a2614bd821fd44cbd1034004ab Mon Sep 17 00:00:00 2001 From: sjfkai Date: Fri, 22 Jan 2016 10:21:49 +0800 Subject: [PATCH 11/27] translate 21 --- README-zh_CN.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README-zh_CN.md b/README-zh_CN.md index 9704bfa5..6354361d 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -18,6 +18,36 @@ # 小知识列表 +## #21 - 对数组洗牌 + +> 2016-01-21 by [@0xmtn](https://github.com/0xmtn/) + + 这段代码运用了[Fisher-Yates Shuffling](https://www.wikiwand.com/en/Fisher%E2%80%93Yates_shuffle)算法对数组进行洗牌。 + +```javascript +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; +}; +``` +调用示例: + +```javascript +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 - 返回对象,使方法可以链式调用([原文](https://github.com/loverajoel/jstips#20---return-objects-to-enable-chaining-of-functions)) > 2016-01-20 by [@WakeskaterX](https://twitter.com/WakeStudio) From 41c5f245cb97be63e8599bbf4fa4aeefb189ed5f Mon Sep 17 00:00:00 2001 From: sjfkai Date: Fri, 22 Jan 2016 10:49:11 +0800 Subject: [PATCH 12/27] fix merge incomplete error --- README-zh_CN.md | 402 +++++------------------------------------------- 1 file changed, 37 insertions(+), 365 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 34363ed1..022ec4f4 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,6 +1,6 @@ ![header](https://raw.githubusercontent.com/loverajoel/jstips/master/resources/jstips-header-blog.gif) -<<<<<<< HEAD + # 关于 JavaScript Tips [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) > 新年, 新项目. **每天一条JS小知识!** @@ -359,41 +359,7 @@ function CounterD() { 快速的测量javascript的性能,我们可以使用console的方法,例如 [```console.time(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimelabel) 和 [```console.timeEnd(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimeendlabel) -======= - - -# JavaScript 贴士介绍 -> 新年,新项目。**每天一个 JS 贴士!** - -With great excitement, I introduce these short and useful daily Javascript tips that will allow you to improve your code writing. With less than 2 minutes each day, you will be able to read about performance, conventions, hacks, interview questions and all the items that the future of this awesome language holds for us. - -At midday, no matter if it is a weekend or a holiday, a tip will be posted and tweeted. - -### Can you help us enrich it? -Please feel free to send us a PR with your own Javascript tip to be published here. -Any improvements or suggestions are more than welcome! -[Click to see the instructions](https://github.com/loverajoel/jstips/blob/master/CONTRIBUTING.md) - -### Let’s keep in touch -To get updates, watch the repo and follow the [Twitter account](https://twitter.com/tips_js), only one tweet will be sent per day. It is a deal! -> Don't forget to Star the repo, as this will help to promote the project! - - - -# 贴士列表 - -## #13 - Tip to measure performance of a javascript block -2016-01-13 by [@manmadareddy](https://twitter.com/manmadareddy) - -For quickly measuring performance of a javascript block, we can use the console functions like -[```console.time(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimelabel) and [```console.timeEnd(label)```](https://developer.chrome.com/devtools/docs/console-api#consoletimeendlabel) ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript console.time("Array initialize"); @@ -407,7 +373,7 @@ for (i = 0; i < len; i++) { console.timeEnd("Array initialize"); // Outputs: Array initialize: 0.711ms ``` -<<<<<<< HEAD + 更多内容: [Console object](https://github.com/DeveloperToolsWG/console-object), [Javascript benchmarking](https://mathiasbynens.be/notes/javascript-benchmarking) @@ -416,24 +382,12 @@ Demo: [jsfiddle](https://jsfiddle.net/meottb62/) - [codepen](http://codepen.io/a ## #12 - ES6中的伪强制参数 #ES6([原文](https://github.com/loverajoel/jstips#12---pseudomandatory-parameters-in-es6-functions-es6)) -======= -More info: -[Console object](https://github.com/DeveloperToolsWG/console-object), -[Javascript benchmarking](https://mathiasbynens.be/notes/javascript-benchmarking) - -Demo: [jsfiddle](https://jsfiddle.net/meottb62/) - [codepen](http://codepen.io/anon/pen/JGJPoa) (outputs in browser console) - -## #12 - Pseudomentatory parameters in ES6 functions ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 > 2016-01-12 by [Avraam Mavridis](https://github.com/AvraamMavridis) -<<<<<<< HEAD + 在许多编程语言中,方法的参数时默认强制需要的,开发人员需要明确定义一个可选的参数。在Javascript中任何参数都是可选的,但是我们可以利用[**es6参数默认值**](http://exploringjs.com/es6/ch_parameter-handling.html#sec_parameter-default-values)特性的优点来实现强制要求这种表现而不污染本身的函数体。 -======= -In many programming languages the parameters of a function is by default mandatory and the developer has to explicitly define that a parameter is optional. In Javascript every parameter is optional, but we can enforce this behavior without messing the actual body of a function taking advantage of the [**es6's default values for parameters**] (http://exploringjs.com/es6/ch_parameter-handling.html#sec_parameter-default-values) feature. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript const _err = function( message ){ @@ -446,7 +400,7 @@ getSum( 10 ) // throws Error, b is not defined getSum( undefined, 10 ) // throws Error, a is not defined ``` -<<<<<<< HEAD + `_err`方法会立即抛出一个错误。如果没有传递值给参数,默认值将会被使用, `_err`方法将被调用而错误也将被抛出。你可以从[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Default_parameters)看到更多关于**默认参数特性**的例子。 @@ -455,14 +409,6 @@ getSum( undefined, 10 ) // throws Error, a is not defined > 2016-01-11 by [@squizzleflip](https://twitter.com/squizzleflip) 了解[变量提升](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var#var_hoisting)可以帮助你组织方法作用域。只要记住变量生命和方法生命都会被提升到顶部。变量的定义不会提升,即使你在同一行声明和定义一个变量。变量**声明**是让系统知道有这个变量存在而**定义**是给其赋值。 -======= - `_err` is a function that immediately throws an Error. If no value is passed for one of the parameters, the default value is gonna be used, `_err` will be called and an Error will be throwed. You can see more examples for the **default parameters feature** on [Mozilla's Developer Network ](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/default_parameters) - -## #11 - Hoisting -> 2016-01-11 by [@squizzleflip](https://twitter.com/squizzleflip) - -Understanding [hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) will help you organize your function scope. Just remember, variable declaration and function definition are hoisted to the top. Variable definition is not, even if you declare and define a variable on the same line. Also, variable **declaration** is letting the system know that the variable exists while **definition** is assigning it a value. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript function doTheThing() { @@ -499,7 +445,7 @@ function doTheThing() { } ``` -<<<<<<< HEAD + 为了让你的代码更易读,将所有的变量声明在函数的顶端,这样可以更清楚的知道变量来自哪个作用域。在使用变量之前声明变量。将方法定义在函数的底部。 ## #10 - 检查某对象是否有某属性([原文](https://github.com/loverajoel/jstips#10---check-if-a-property-is-in-a-object)) @@ -507,22 +453,13 @@ function doTheThing() { > 2016-01-10 by [@loverajoel](https://www.twitter.com/loverajoel) 当你需要检查某属性是否存在于一个[对象](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects),你可能会这样做: -======= -To make things easier to read, declare all of your variables at the top of your function scope so it is clear which scope the variables are coming from. Define your variables before you need to use them. Define your functions at the bottom of your scope to keep them out of your way. - -## #10 - Check if a property is in a Object - -> 2016-01-10 by [@loverajoel](https://www.twitter.com/loverajoel) - -When you have to check if a property is present of an [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects), you probably are doing something like this: ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var myObject = { name: '@tips_js' }; -<<<<<<< HEAD + if (myObject.name) { ... } ``` @@ -530,15 +467,6 @@ if (myObject.name) { ... } 这是可以的,但是你需要知道有两种原生方法可以解决此类问题。[`in` 操作符](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/in) 和 [`Object.hasOwnProperty`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty),任何继承自`Object`的对象都可以使用这两种方法。 ### 看一下较大的区别 -======= -if (myObject['name']) { ... } - -``` - -Thats ok, but you have to know that there are two native ways for this kind of thing, the [`in` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in) and [`Object.hasOwnProperty`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), every object descended from `Object`, has available both ways. - -### See the big Difference ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var myObject = { @@ -548,24 +476,16 @@ var myObject = { myObject.hasOwnProperty('name'); // true 'name' in myObject; // true -<<<<<<< HEAD + myObject.hasOwnProperty('valueOf'); // false, valueOf 继承自原型链 -======= -myObject.hasOwnProperty('valueOf'); // false, valueOf is inherited from the prototype chain ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 'valueOf' in myObject; // true ``` -<<<<<<< HEAD + 两者检查属性的深度不同,换言之`hasOwnProperty`只在本身有此属性时返回true,而`in`操作符不区分属性来自于本身或继承自原型链。 这是另一个例子 -======= -Both differs in the depth how check the properties, in other words `hasOwnProperty` will only return true if key is available on that object directly, however `in` operator doesn't discriminate between properties created on an object and properties inherited from the prototype chain. - -Here another example ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var myFunc = function() { @@ -576,7 +496,7 @@ myFunc.prototype.age = '10 days'; var user = new myFunc(); user.hasOwnProperty('name'); // true -<<<<<<< HEAD + user.hasOwnProperty('age'); // false, 因为age来自于原型链 ``` @@ -592,34 +512,14 @@ ES6中,JS现在有了引号拼接字符串的替代品,模板字符串。 示例: 普通字符串 -======= -user.hasOwnProperty('age'); // false, because age is from the prototype chain -``` - -Check here the [live examples](https://jsbin.com/tecoqa/edit?js,console)! - -Also recommends read [this discussion](https://github.com/loverajoel/jstips/issues/62) about common mistakes at checking properties' existence in objects - -## #09 - Template Strings - -> 2016-01-09 by [@JakeRawr](https://github.com/JakeRawr) - -As of ES6, JS now has template strings as an alternative to the classic end quotes strings. - -Ex: -Normal string ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var firstName = 'Jake'; var lastName = 'Rawr'; console.log('My name is ' + firstName + ' ' + lastName); // My name is Jake Rawr ``` -<<<<<<< HEAD + 模板字符串 -======= -Template String ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var firstName = 'Jake'; var lastName = 'Rawr'; @@ -627,7 +527,7 @@ console.log(`My name is ${firstName} ${lastName}`); // My name is Jake Rawr ``` -<<<<<<< HEAD + 在模板字符串中,你可以不用`\n`来生成多行字符串还可以在`${}`里做简单的逻辑运算(例如 2+3)。 你也可以使用方法修改模板字符串的输出内容;他们被称为[带标签的模板字符串](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings#Tagged_template_strings)(其中有带标签的模板字符串的示例) @@ -639,36 +539,19 @@ console.log(`My name is ${firstName} ${lastName}`); > 2016-01-08 by [@Tevko](https://twitter.com/tevko) `querySelectorAll`方法返回一个类数组对象称为node list。这些数据结构被称为“类数组”,因为他们看似数组却没有类似`map`、`foreach`这样的数组方法。这是一个快速、安全、可重用的方法将node list转换为DOM元素的数组: -======= -You can do Multi-line strings without `\n` and simple logic (ie 2+3) inside `${}` in Template String. - -You are also able to to modify the output of template strings using a function; they are called [Tagged template strings] -(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings#Tagged_template_strings) for example usages of tagged template strings. - -You may also want to [read](https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2) to understand template strings more - -## #08 - Converting a Node List to an Array - -> 2016-01-08 by [@Tevko](https://twitter.com/tevko) - -The `querySelectorAll` method returns an array-like object called a node list. These data structures are referred to as "Array-like", because they appear as an array, but can not be used with array methods like `map` and `foreach`. Here's a quick, safe, and reusable way to convert a node list into an Array of DOM elements: ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript const nodelist = document.querySelectorAll('div'); const nodelistToArray = Array.apply(null, nodelist); -<<<<<<< HEAD + //之后 .. -======= -//later on .. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 nodelistToArray.forEach(...); nodelistToArray.map(...); nodelistToArray.slice(...); -<<<<<<< HEAD + //等... ``` @@ -680,25 +563,12 @@ nodelistToArray.slice(...); const nodelist = [...document.querySelectorAll('div')]; // 返回一个真正的数组 //之后 .. -======= -//etc... -``` - -The `apply` method is used to pass an array of arguments to a function with a given `this` value. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) states that `apply` will take an array like object, which is exactly what `querySelectorAll` returns. Since we don't need to specify a value for `this` in the context of the function, we pass in `null` or `0`. The result is an actual array of DOM elements which contains all of the available array methods. - -Or if you are using ES2015 you can use the [spread operator `...`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) - -```js -const nodelist = [...document.querySelectorAll('div')]; // returns a real Array - -//later on .. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 nodelist.forEach(...); nodelist.map(...); nodelist.slice(...); -<<<<<<< HEAD + //等... ``` @@ -718,43 +588,18 @@ JavaScript的严格模式使开发者更容易写出“安全”的代码。 ```javascript // 全脚本严格模式 -======= -//etc... -``` - -## #07 - "use strict" and get lazy - -> 2016-01-07 by [@nainslie](https://twitter.com/nat5an) - -Strict-mode JavaScript makes it easier for the developer to write "secure" JavaScript. - -By default, JavaScript allows the programmer to be pretty careless, for example, by not requiring us to declare our variables with "var" when we first introduce them. While this may seem like a convenience to the unseasoned developer, it's also the source of many errors when a variable name is misspelled or accidentally referred to out of its scope. - -Programmers like to make the computer do the boring stuff for us, and automatically check our work for mistakes. That's what the JavaScript "use strict" directive allows us to do, by turning our mistakes into JavaScript errors. - -We add this directive either by adding it at the top of a js file: - -```javascript -// Whole-script strict mode syntax ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 "use strict"; var v = "Hi! I'm a strict mode script!"; ``` -<<<<<<< HEAD + 或者放在一个方法内: -======= -or inside a function: ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript function f() { -<<<<<<< HEAD + // 方法级严格模式 -======= - // Function-level strict mode syntax ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 'use strict'; function nested() { return "And so am I!"; } return "Hi! I'm a strict mode function! " + nested(); @@ -762,7 +607,7 @@ function f() function f2() { return "I'm not strict."; } ``` -<<<<<<< HEAD + 通过在JavaScript文件或方法内引入此指令,使JavaScript引擎运行在严格模式下,这直接禁止了许多大项目中不受欢迎的操作。另外,严格模式也改变了以下行为: * 只有被"var"声明过的变量才可以引用。 * 试图写只读变量时将会报错 @@ -775,27 +620,13 @@ function f2() { return "I'm not strict."; } It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. 严格模式的支持情况: -======= -By including this directive in a JavaScript file or function, we will direct the JavaScript engine to execute in strict mode which disables a bunch of behaviors that are usually undesirable in larger JavaScript projects. Among other things, strict mode changes the following behaviors: -* Variables can only be introduced when they are preceded with "var" -* Attempting to write to readonly properties generates a noisy error -* You have to call constructors with the "new" keyword -* "this" is not implicitly bound to the global object -* Very limited use of eval() allowed -* Protects you from using reserved words or future reserved words as variable names - -Strict mode is great for new projects, but can be challenging to introduce into older projects that don't already use it in most places. It also can be problematic if your build chain concatenates all your js files into one big file, as this may cause all files to execute in strict mode. - -It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. -Strict mode is supported in: ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 * Internet Explorer from version 10. * Firefox from version 4. * Chrome from version 13. * Safari from version 5.1. * Opera from version 12. -<<<<<<< HEAD + [MDN对严格模式的全面介绍](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode) ## #06 - 可以接受单各参数和数组的方法 @@ -805,17 +636,6 @@ Strict mode is supported in: 写一个方法可以接受单个参数也可以接受一个数组,而不是分开写两个方法。这和jQuery的一些方法的工作原理很像(`css` 可以修改任何匹配到的选择器). 你只要把任何东西连接到一个数组. `Array.concat`可以接受一个数组也可以接受单个参数。 -======= -[See MDN for a fuller description of strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). - -## #06 - Writing a single method for arrays or single elements - -> 2016-01-06 by [@mattfxyz](https://twitter.com/mattfxyz) - -Rather than writing separate methods to handle an array and a single element parameter, write your functions so they can handle both. This is similar to how some of jQuery's functions work (`css` will modify everything matched by the selector). - -You just have to concat everything into an array first. `Array.concat` will accept an array or a single element. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript function printUpperCase(words) { @@ -826,11 +646,8 @@ function printUpperCase(words) { } ``` -<<<<<<< HEAD + `printUpperCase`现在可以接受单个单词或多个单词的数组作为它的参数。 -======= -`printUpperCase` is now ready to accept a single node or an array of nodes as its parameter. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript printUpperCase("cactus"); @@ -841,7 +658,7 @@ printUpperCase(["cactus", "bear", "potato"]); // POTATO ``` -<<<<<<< HEAD + ## #05 - `undefined`与`null`的区别([原文](https://github.com/loverajoel/jstips#05---differences-between-undefined-and-null)) > 2016-01-05 by [@loverajoel](https://twitter.com/loverajoel) @@ -857,41 +674,18 @@ printUpperCase(["cactus", "bear", "potato"]); - 他们都是[falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) (`Boolean(undefined) // false`, `Boolean(null) // false`) - 你可以这样判断一个变量是否是[undefined](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined) -======= -## #05 - Differences between `undefined` and `null` - -> 2016-01-05 by [@loverajoel](https://twitter.com/loverajoel) - -- `undefined` means a variable has not been declared, or has been declared but has not yet been assigned a value -- `null` is an assignment value that means "no value" -- Javascript sets unassigned variables with a default value of `undefined` -- Javascript never sets a value to `null`. It is used by programmers to indicate that a `var` has no value. -- `undefined` is not valid in JSON while `null` is -- `undefined` typeof is `undefined` -- `null` typeof is an `object` -- Both are primitives -- Both are [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) - (`Boolean(undefined) // false`, `Boolean(null) // false`) -- You can know if a variable is [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined) ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript typeof variable === "undefined" ``` -<<<<<<< HEAD + - 你可以这样判断一个变量是否是[null](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/null) -======= -- You can check if a variable is [null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null) ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript variable === null ``` -<<<<<<< HEAD + - **双等号**比较时它们相等,但**三等号**比较时不相等 -======= -- The **equality** operator considers them equal, but the **identity** doesn't ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript null == undefined // true @@ -899,26 +693,19 @@ printUpperCase(["cactus", "bear", "potato"]); null === undefined // false ``` -<<<<<<< HEAD + ## #04 - 排列带音节字母的字符串([原文](https://github.com/loverajoel/jstips#04---sorting-strings-with-accented-characters)) > 2016-01-04 by [@loverajoel](https://twitter.com/loverajoel) Javascript有一个原生方法**[sort](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)**可以排列数组。一次简单的`array.sort()`将每一个数组元素视为字符串并按照字母表排列。你也可以提供[自定义排列方法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters) function. -======= -## #04 - Sorting strings with accented characters - -> 2016-01-04 by [@loverajoel](https://twitter.com/loverajoel) - -Javascript has a native method **[sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)** that allows sorting arrays. Doing a simple `array.sort()` will treat each array entry as a string and sort it alphabetically. Also you can provide your [own custom sorting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters) function. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript ['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); // ["Buenos Aires", "Mumbai", "New York", "Shanghai"] ``` -<<<<<<< HEAD + 但是当你试图整理一个如`['é', 'a', 'ú', 'c']`这样的非ASCII元素的数组时,你可能会得到一个奇怪的结果`['c', 'e', 'á', 'ú']`。这是因为排序方法只在英文下有用。 看一下下一个例子: @@ -929,35 +716,16 @@ Javascript has a native method **[sort](https://developer.mozilla.org/en-US/docs // ["cosas", "fútbol", "árbol", "único"] // bad order // 德语 -======= -But when you try order an array of non ASCII characters like this `['é', 'a', 'ú', 'c']`, you will obtain a strange result `['c', 'e', 'á', 'ú']`. That happens because sort works only with english language. - -See the next example: - -```javascript -// Spanish -['único','árbol', 'cosas', 'fútbol'].sort(); -// ["cosas", "fútbol", "árbol", "único"] // bad order - -// German ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); // ["Wann", "Woche", "wäre", "wöchentlich"] // bad order ``` -<<<<<<< HEAD + 幸运的是,有两种方法可以解决这个问题,由ECMAScript国际化API提供的[localeCompare](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)和[Intl.Collator](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Collator)。 > 两个方法都有自定义配置参数可以使其更好用。 ### 使用`localeCompare()` -======= -Fortunately, there are two ways to overcome this behavior [localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) and [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator) provided by ECMAScript Internationalization API. - -> Both methods have their own custom parameters in order to configure it to work adequately. - -### Using `localeCompare()` ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript ['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) { @@ -971,11 +739,8 @@ Fortunately, there are two ways to overcome this behavior [localeCompare](https: // ["Wann", "wäre", "Woche", "wöchentlich"] ``` -<<<<<<< HEAD + ### 使用`Intl.Collator()` -======= -### Using `Intl.Collator()` ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript ['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare); @@ -985,7 +750,7 @@ Fortunately, there are two ways to overcome this behavior [localeCompare](https: // ["Wann", "wäre", "Woche", "wöchentlich"] ``` -<<<<<<< HEAD + - 两个方法都可以自定义区域位置。For each method you can customize the location. - 根据[Firefox](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance),当比较大数量的字符串是Intl.Collator更快。 @@ -995,17 +760,6 @@ Fortunately, there are two ways to overcome this behavior [localeCompare](https: > 2016-01-03 by [AlbertoFuente](https://github.com/AlbertoFuente) 我们怎样来提高和优化javascript里嵌套的`if`语句呢? -======= -- For each method you can customize the location. -- According to [Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance) Intl.Collator is faster when comparing large numbers of strings. - -So when you are working with arrays of strings in a language other than English, remember to use this method to avoid unexpected sorting. - -## #03 - Improve Nested Conditionals -> 2016-01-03 by [AlbertoFuente](https://github.com/AlbertoFuente) - -How can we improve and make more efficient nested `if` statement in javascript. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript if (color) { @@ -1023,11 +777,8 @@ if (color) { } ``` -<<<<<<< HEAD + 一种方法来提高嵌套的`if`语句是用`switch`语句。虽然它不那么啰嗦而且排列整齐,但是并不建议使用它,因为这对于调试错误很困难。这告诉你[为什么](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals/). -======= -One way to improve the nested `if` statement would be using the `switch` statement. Although it is less verbose and is more ordered, It's not recommended to use it because it's so difficult to debug errors, here's [why](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals/). ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript switch(color) { @@ -1048,12 +799,8 @@ switch(color) { } ``` -<<<<<<< HEAD + 但是如果在每个语句中都有很多条件检查时该怎么办呢?这种情况下,如果我们想要不罗嗦又整洁的话,我们可以用有条件的`switch`。如果我们传递`true`给`switch`语句,我没变可以在每个case中使用条件语句了。 -======= -But what if we have a conditional with several checks in each statement? In this case, if we like to do less verbose and more ordered, we can use the conditional `switch`. -If we pass `true` as parameter to the `switch` statement, It allows us to put a conditional in each case. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript switch(true) { @@ -1075,11 +822,8 @@ switch(true) { } ``` -<<<<<<< HEAD + 但是我们应该时刻注意避免太多判断在一个条件里,尽量少的使用`switch`,考虑最有效率的方法:借助`object`。 -======= -But we must always avoid having several checks in every condition, avoiding use of `switch` as far as possible and take into account that the most efficient way to do this is through an `object`. ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var colorObj = { @@ -1090,26 +834,18 @@ var colorObj = { 'yellow': printYellowBackground }; -<<<<<<< HEAD + if (color in colorObj) { -======= -if (color && colorObj.hasOwnProperty(color)) { ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 colorObj[color](); } ``` -<<<<<<< HEAD + 这里有更多相关的[内容](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/). ## #02 - ReactJs - Keys in children components are important([原文](https://github.com/loverajoel/jstips#02---reactjs---keys-in-children-components-are-important)) (译者注:本人对ReactJs了解不多,就不翻译了,免得误导大家 欢迎PR) -======= -Here you can find more information about [this](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/). - -## #02 - ReactJs - Keys in children components are important ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 > 2016-01-02 by [@loverajoel](https://twitter.com/loverajoel) @@ -1144,13 +880,10 @@ The [key](https://facebook.github.io/react/docs/multiple-components.html#dynamic - When the amount of child are big or involve expensive components, use keys has performance improvements. - [You must provide the key attribute for all children of ReactCSSTransitionGroup.](http://docs.reactjs-china.com/react/docs/animation.html) -<<<<<<< HEAD + ## #1 - AngularJs: `$digest` vs `$apply`([原文](https://github.com/loverajoel/jstips#1---angularjs-digest-vs-apply)) (译者注:本人对AngularJs了解不多,就不翻译了,免得误导大家 欢迎PR) -======= -## #1 - AngularJs: `$digest` vs `$apply` ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 > 2016-01-01 by [@loverajoel](https://twitter.com/loverajoel) @@ -1181,7 +914,7 @@ In this case the `$digest` method starts the `$digest` cycle for the current sco - If you are using >AngularJS 1.2.X, use `$evalAsync` is a core method that will evaluate the expression during the current cycle or the next. This can improve your application's performance. -<<<<<<< HEAD + ## #0 - 向数组中插入元素([原文](https://github.com/loverajoel/jstips#0---insert-item-inside-an-array)) > 2015-12-29 @@ -1190,97 +923,36 @@ In this case the `$digest` method starts the `$digest` cycle for the current sco 但是这些已知的方法,并不意味着没有更加高效的方法。让我们接着往下看…… 向数组结尾添加元素用push()很简单,但下面有一个更高效的方法 -======= - - -## #0 - 插入一项元素到数组中 -> 2015-12-29 - - - -在已存在的数组中插入一项元素是一件日常任务。你可以使用 `push` -操作把元素添加到数组的末尾,使用 `unshift` 操作添加到开头,或者使用 `splice` -添加到中间。 - -但这些都是已知的方法,并不意味着没有性能更好的方式,我们开始吧…… - -`push()` 可以很容易地把一个元素添加到数组的末尾,但这里有个更高效的方式。 - ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var arr = [1,2,3,4,5]; arr.push(6); -<<<<<<< HEAD + arr[arr.length] = 6; // 在Mac OS X 10.11.1下的Chrome 47.0.2526.106中快43% ``` 两种方法都是修改原始数组。不信?看看[jsperf](http://jsperf.com/push-item-inside-an-array) 现在我们试着向数组的头部添加元素: -======= -arr[arr.length] = 6; // 43% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1 -``` - - -这两个方法都修改了原始数组。不相信我?瞧这里 [jsperf](http://jsperf.com/push-item-inside-an-array)。 - -现在,我们试着把元素添加到数组的开头。 ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var arr = [1,2,3,4,5]; arr.unshift(0); -<<<<<<< HEAD + [0].concat(arr); // 在Mac OS X 10.11.1下的Chrome 47.0.2526.106中快98% ``` 这里有一些小区别,unshift操作的是原始数组,concat返回一个新数组,参考[jsperf](http://jsperf.com/unshift-item-inside-an-array) 使用splice可以简单的向数组总监添加元素,这也是最高效的方法。 -======= -[0].concat(arr); // 98% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1 -``` - - -这里有个小细节,`unshift` 对原始数组进行编辑,而 `concat` 返回一个新数组。[jsperf](http://jsperf.com/unshift-item-inside-an-array) - -使用 `splice` 可以很容易地把元素添加到数组的中间,而且这样做是最高效的。 - ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 ```javascript var items = ['one', 'two', 'three', 'four']; items.splice(items.length / 2, 0, 'hello'); ``` -<<<<<<< HEAD -我在许多浏览器和系统中进行了测试,结果都是相似的。希望这条小知识可以帮到你,也欢迎大家自行测试。 -======= - - -我已经在许多浏览器和操作系统,试着去运行这些测试,并且它们的结果非常相似。 -我希望这些贴士(建议)对你有用,并鼓励进行自己的测试! ->>>>>>> 10349441e922d485cef40970c3b92b717e2d0996 +我在许多浏览器和系统中进行了测试,结果都是相似的。希望这条小知识可以帮到你,也欢迎大家自行测试。 ### License [![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/) From 31783ef3ae77e36dc22f9be12d263afc6938ca86 Mon Sep 17 00:00:00 2001 From: sjfkai Date: Sat, 23 Jan 2016 10:00:52 +0800 Subject: [PATCH 13/27] translate 22 --- README-zh_CN.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/README-zh_CN.md b/README-zh_CN.md index 022ec4f4..495d975b 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -19,6 +19,55 @@ # 小知识列表 +## #22 - 清空数组 + +> 2016-01-22 by [microlv](https://github.com/microlv) + +如果你定义了一个数组,然后你想清空它。 +通常,你会这样做: + +```javascript +// 定义一个数组 +var list = [1, 2, 3, 4]; +function empty() { + //清空数组 + list = []; +} +empty(); +``` +但是,这有一个效率更高的方法来清空数组。 +你可以这样写: +```javascript +var list = [1, 2, 3, 4]; +function empty() { + //empty your array + list.length = 0; +} +empty(); +``` +* `list = []` 将一个新的数组的引用赋值给变量,其他引用并不受影响。 +这意味着以前数组的内容被引用的话将依旧存在于内存中,这将导致内存泄漏。 + +* `list.length = 0` 删除数组里的所有内容,也将影响到其他引用。 + +然而,如果你复制了一个数组(A 和 Copy-A),如果你用`list.length = 0`清空了它的内容,复制的数组也会清空它的内容。 + +考虑一下将会输出什么: +```js +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](http://stackoverflow.com/questions/4804235/difference-between-array-length-0-and-array) + + ## #21 - 对数组洗牌 > 2016-01-21 by [@0xmtn](https://github.com/0xmtn/) From 5dc3c347f050064526d333192371414b9891103d Mon Sep 17 00:00:00 2001 From: sjfkai Date: Sat, 23 Jan 2016 10:07:31 +0800 Subject: [PATCH 14/27] add tip21 and tip22's original link --- README-zh_CN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README-zh_CN.md b/README-zh_CN.md index 495d975b..6c045e6e 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -19,7 +19,7 @@ # 小知识列表 -## #22 - 清空数组 +## #22 - 清空数组([原文](https://github.com/loverajoel/jstips#22---empty-an-array)) > 2016-01-22 by [microlv](https://github.com/microlv) @@ -68,7 +68,7 @@ console.log(foo, bar, foo2, bar2); [difference-between-array-length-0-and-array](http://stackoverflow.com/questions/4804235/difference-between-array-length-0-and-array) -## #21 - 对数组洗牌 +## #21 - 对数组洗牌([原文](https://github.com/loverajoel/jstips#21---shuffle-an-array)) > 2016-01-21 by [@0xmtn](https://github.com/0xmtn/) From 9c23bbdb9a32debf9a90b6e93da9a1e292191f8c Mon Sep 17 00:00:00 2001 From: sjfkai Date: Sun, 24 Jan 2016 10:30:50 +0800 Subject: [PATCH 15/27] translate 23 --- README-zh_CN.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README-zh_CN.md b/README-zh_CN.md index 6c045e6e..381c11c3 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -19,6 +19,26 @@ # 小知识列表 +## #23 - 转换为数字的更快方法([原文](https://github.com/loverajoel/jstips#23---converting-to-number-fast-way)) + +> 2016-01-23 by [@sonnyt](http://twitter.com/sonnyt) + +将字符串转换为数字是极为常见的。最简单和快速的方法([jsPref](https://jsperf.com/number-vs-parseint-vs-plus/29))`+`(加号) 来实现。 + +```javascript +var one = '1'; + +var numberOne = +one; // Number 1 +``` + +你也可以用`-`(减号)将其转化为负数值。 + +```javascript +var one = '1'; + +var negativeNumberOne = -one; // Number -1 +``` + ## #22 - 清空数组([原文](https://github.com/loverajoel/jstips#22---empty-an-array)) > 2016-01-22 by [microlv](https://github.com/microlv) From a36bd87bc69a5a55f97586bfbd1b631f2dd4d4ed Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Fri, 5 Feb 2016 10:58:57 -0200 Subject: [PATCH 16/27] Translate to Portuguese_BR --- CONTRIBUTING_pt_BR.md | 11 +++++ _config.yml | 28 +++++++++++ .../2015-12-29-insert-item-inside-an-array.md | 46 ++++++++++++++++++ .../2016-01-01-angularjs-digest-vs-apply.md | 36 ++++++++++++++ ...ys-in-children-components-are-important.md | 42 ++++++++++++++++ images/flags/pt_BR.png | Bin 0 -> 2315 bytes pt_BR/about.md | 36 ++++++++++++++ pt_BR/index.html | 4 ++ 8 files changed, 203 insertions(+) create mode 100644 CONTRIBUTING_pt_BR.md create mode 100644 _posts/pt_BR/2015-12-29-insert-item-inside-an-array.md create mode 100644 _posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md create mode 100644 _posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md create mode 100644 images/flags/pt_BR.png create mode 100644 pt_BR/about.md create mode 100644 pt_BR/index.html diff --git a/CONTRIBUTING_pt_BR.md b/CONTRIBUTING_pt_BR.md new file mode 100644 index 00000000..0e545a84 --- /dev/null +++ b/CONTRIBUTING_pt_BR.md @@ -0,0 +1,11 @@ +# Como enviar sua dica + +Para enviar uma dica para a lista, dê um fork nesse repositório e adicione sua dica em um novo arquivo na pasta correta (de acordo com o idioma). O nome do arquivo deve ser `2016-xx-xx-nome-da-sua-dica`. + +Use [este formato](https://github.com/loverajoel/jstips/blob/gh-pages/POST_TEMPLATE.md) quando escrever sua dica. Sua dica deve poder ser lida em menos de dois minutos. Você pode adicionar links para outros sites ou vídeos que darão uma ideia mais clara, se desejar. + +Quando sua dica estiver pronta, [envie um pull request](https://help.github.com/articles/using-pull-requests/) com este [template de PR](https://github.com/loverajoel/jstips/blob/gh-pages/GIT_TEMPLATE.md) e sua dica será revisada. Todo dia uma dica será aceita a partir dos pull requests disponíveis. + +# Notas + +Deixar a data e o número da dica com **xx**. Quando decidirmos unir o pull request você irá adicioná-los em seus commits. diff --git a/_config.yml b/_config.yml index 49612db4..1c393682 100644 --- a/_config.yml +++ b/_config.yml @@ -33,6 +33,14 @@ defaults: layout: default lang: zh_CN is_post: true + - + scope: + path: _posts/pt_BR + type: posts + values: + layout: default + lang: pt_BR + is_post: true # Enter your Disqus shortname (not your username) to enable commenting on posts # You can find your shortname on the Settings page of your Disqus account @@ -91,6 +99,9 @@ languages: - name: zh_CN link: /zh_CN + - + name: pt_BR + link: /pt_BR transl: en: @@ -127,3 +138,20 @@ transl: footer_placeholder_subscribe: your@email.com arrow_prev: 上一条 arrow_next: 下一条 + pt_BR: + menu: + home: + txt: Home + link: /pt_BR + about: + txt: Sobre + link: /pt_BR/about + subscribe: + txt: Inscreva-se + submit_your_tip: + txt: Envie sua dica + link: https://github.com/loverajoel/jstips/blob/gh-pages/CONTRIBUTING_pt_BR.md + footer_subscribe_message: Subscribe to more awesome daily tips! + footer_placeholder_subscribe: seu@email.com + arrow_prev: Dica anterior + arrow_next: Próxima dica diff --git a/_posts/pt_BR/2015-12-29-insert-item-inside-an-array.md b/_posts/pt_BR/2015-12-29-insert-item-inside-an-array.md new file mode 100644 index 00000000..253286c4 --- /dev/null +++ b/_posts/pt_BR/2015-12-29-insert-item-inside-an-array.md @@ -0,0 +1,46 @@ +--- +layout: post + +title: Inserir item em um array +tip-number: 00 +tip-username: loverajoel +tip-username-profile: https://github.com/loverajoel +tip-tldr: Inserir um item em um array existente é muito comum diariamente. Você pode adicionar elementos no final de um array usando push, no começo usando unshift ou no meio usando splice. + + +categories: + - pt_br +--- + +Inserir um item em um array existente é muito comum diariamente. Você pode adicionar elementos no final de um array usando push, no começo usando unshift ou no meio usando splice. + +Estes são métodos conhecidos, mas não significa que não exista uma forma mais performática. Vamos lá: + +Adicionar um elemento no final de um array é fácil com push(), mas há uma forma com melhor performance. + +```javascript +var arr = [1,2,3,4,5]; + +arr.push(6); +arr[arr.length] = 6; // 43% mais rápido no Chrome 47.0.2526.106 no Mac OS X 10.11.1 +``` +Ambos os métodos modificam o array original. Não acredita? Veja o [jsperf](http://jsperf.com/push-item-inside-an-array) + +Agora se estivermos tentando adicionar um item no começo do array: + +```javascript +var arr = [1,2,3,4,5]; + +arr.unshift(0); +[0].concat(arr); // 98% mais rápido no Chrome 47.0.2526.106 no Mac OS X 10.11.1 +``` +Mais um detalhe: unshift edita o array original; concat retorna um novo array. [jsperf](http://jsperf.com/unshift-item-inside-an-array) + +Adicionar itens na metade do array é simples com splice, e há uma maneira mais performática de fazer isto. + +```javascript +var items = ['one', 'two', 'three', 'four']; +items.splice(items.length / 2, 0, 'hello'); +``` + +Eu tentei executar estes testes em vários Browsers e SO e o resultado foi similar. Espero que estas dicas sejam úteis para você e o encoraje a realizar seus próprios testes de performance! \ No newline at end of file diff --git a/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md b/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md new file mode 100644 index 00000000..c083d604 --- /dev/null +++ b/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md @@ -0,0 +1,36 @@ +--- +layout: post + +title: AngularJs - `$digest` vs `$apply` +tip-number: 01 +tip-username: loverajoel +tip-username-profile: https://github.com/loverajoel +tip-tldr: JavaScript modules e build steps estão ficando numerosos e complicados, mas e boilerplate e novos frameworks? + +categories: + - pt_br +--- + +Uma das características mais apreciadas do AngularJs é o two-way data binding. Para fazer este trabalho o AngularJs avalia as mudanças entre o model e a view através de ciclos ( $digest ). Você precisa entender esse conceito para entender como o framework funciona debaixo do capô. + +Angular avalia cada observador quando um evento é disparado. Esse é o ciclo conhecido como `$digest`. Algumas vezes você precisa forçar a execução de um novo ciclo manualmente e deve escolher a opção correta pois esta fase é uma das que mais influencia em termos de performance. + +### `$apply` +Este método do core permite você iniciar o ciclo digestion explicitamente. Isso significa que todos os observadores são verificados; toda a aplicação inicia o `$digest loop`. Internamente, depois de executar um parâmetro de função opcional, ele chama `$rootScope.$digest();`. + +### `$digest` +Nesse caso o método `$digest` inicia o ciclo `$digest` para o escopo atual e seu filhos. Você deve notar que os escopos pais não serão verificados e afetados. + +### Recomendações +- Use `$apply` ou `$digest` somente quando os eventos DOM do navegador forem provocados fora do AngularJs. +- Passe uma expressão de função para `$apply`, ele tem um mecanismo de tratamento de erros e permite integrar as mudanças no ciclo digest. + +```javascript +$scope.$apply(() => { + $scope.tip = 'Javascript Tip'; +}); +``` + +- Se você só precisa atualizar o escopo atual ou seus filhos, use `$digest`, previnindo um novo ciclo digest para toda a aplicação. O benefício em performance é evidente. +- `$apply()` é um processo difícil para a máquina e pode causar problemas de performance quando se tem muito binding. +- Se você está usando >AngularJS 1.2.X, use `$evalAsync`, um método do core que irá avaliar a expressão durante o ciclo atual ou o próximo. Isto pode melhorar a performance da aplicação. \ No newline at end of file diff --git a/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md new file mode 100644 index 00000000..20823270 --- /dev/null +++ b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md @@ -0,0 +1,42 @@ +--- +layout: post + +title: Keys in children components are important +tip-number: 02 +tip-username: loverajoel +tip-username-profile: https://github.com/loverajoel +tip-tldr: The key is an attribute that you must pass to all components created dynamically from an array. It's a unique and constant id that React uses to identify each component in the DOM and to know whether it's a different component or the same one. Using keys ensures that the child component is preserved and not recreated and prevents weird things from happening. + +categories: + - pt_br +--- + +The [key](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children) is an attribute that you must pass to all components created dynamically from an array. It's a unique and constant id that React uses to identify each component in the DOM and to know whether it's a different component or the same one. Using keys ensures that the child component is preserved and not recreated and prevents weird things from happening. + +> Key is not really about performance, it's more about identity (which in turn leads to better performance). Randomly assigned and changing values do not form an identity [Paul O’Shannessy](https://github.com/facebook/react/issues/1342#issuecomment-39230939) + +- Use an existing unique value of the object. +- Define the keys in the parent components, not in child components + +```javascript +//bad +... +render() { +
{{item.name}}
+} +... + +//good + +``` +- [Using array index is a bad practice.](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318#.76co046o9) +- `random()` will not work + +```javascript +//bad + +``` + +- You can create your own unique id. Be sure that the method is fast and attach it to your object. +- When the number of children is large or contains expensive components, use keys to improve performance. +- [You must provide the key attribute for all children of ReactCSSTransitionGroup.](http://docs.reactjs-china.com/react/docs/animation.html) \ No newline at end of file diff --git a/images/flags/pt_BR.png b/images/flags/pt_BR.png new file mode 100644 index 0000000000000000000000000000000000000000..c176098bf3cbbe5419f4c2e9d0f6edda47af41fa GIT binary patch literal 2315 zcmV+m3H0`fP)(_`g8%^e{{R4h=l}px2mk>USO5SzmjD14Z`WEM zkN^M(kx4{BRCwCln`>~C)fvZs=iS|8H+#tj5C~O5E`}xwCdf)0<7hj!O`PgzrK1Hq zN`+~~4r5z&rlKu&&}oNuhG8&RAoWtQWrXRpOq-0>8xsT!;cAkiL6QKQgd}eEzS+xr z`e8#%%w;#5-A(QDCG)O{5v+ElMj?nJ!z#aA=k^Dc4 zKw#FISY*hf(po{Oad8dM1iUWnJ^c@dWccMjcm0*)u2VBIL7jkyOcDXS;t_;qXg`)& zZs3Qx_oEZKHCn*-M%SA&2Fg_$c-*3rr;R=@(n_|v6nZ1+pUZLADKuz!Xu%I`;+@Y9 z%NH-~nh{XSGbE2%Bw1qgd!K}tT!Q04F(dPO?3#6GiXOUtQ+M!kS`{n6_l=T=&5{f; zzG+qHqkmgNBJG|oD1&I*e4nLNsYQXGS|p`98N)Hc-C2?%9c*_ATx$B}c;4TE;)!_E zrm$EC&*!KyK^ZBfI?3}nD#g0=0pkvPP|~HW${^WjRmn*}V~zqFtt!=q^ca;yqD{3D zy?}LQ$%@P`78OwiC)%#!E7>P4eSG{9<8 z)UNGUxQd?ibfHyOt@vO!{9;s@j^13bn0uo+!3l0s6 zuLdwW0jrFXZw>haRSI_1l~R9fVRC%c@=n%Ox1fmV_;33KZ+MfREhp8-%vPeNQ#ces zR4Lf9ubd;T^OB~c{@6kWyqP??@&t;AZa{%nvdyK?pTv-!w5YTsL$W#N3s3-R>r0Xf z$`v`%I*;A;CBx5!I@p|}vLr+P?*Jo!d$S}@WlPK>Mr&x!jd?UQ=MF!c z6?iIJa&K0&7@bj5GAZz=S#radcFG&jvAez$fVp$BD7$_h#f3Rsv%tcfSq4m|40Kur ze;|y<8>FY#N9RQ+EuZvrx}_J7HyD@x-SwrE7xoQDD*@bRjE3|bZh>bSrj@Ys&DX-? z*($TgIdg9|l+dT%&bM#Rry$QdrEwz>m6IP|=B@Y7bL>Jl0=eG3x;cg(6(AyXm~>!r=_y^@UJXiAE7*TQbR= zXCi-LHnVaJW5(*dFO9>>D{(_*tsvvU@&o}sUXkFecvsn;>NEbhBmvW z*T?T`KH^-vW6byOv~{qqx@FQaFNR^OOQAc?X=zHoFO1eB+jDxNynEr7q9tMQ9{=c(Vk&w;nvqFJ?0!xQUo!d9M}kWPbu4Hn62 zQ?w{e2$&oNo*pXor{cPNgUKz}Lt&Md|8j=ywM~S>DjJQ#&wpYge_?h)It5T|kUSlO z0#PQacYbMAS)4|4D3-k2(8(WOY9t(1$;{C3#A7SaXC}T0i*?a8>ckX)2}#)ERA^5i z2gu4y9T#x4$j@Qg#@>^N3q)Q4DG z)sk{x)>XF*b1|bb<`6vNP-qP$PFYQh!E>na!hk}Zf9$SQUe`snEp;YUZR;5B7>qp4 zb$-DM0}765^1sujHY30uk6@ci;QtajYpYtRDCtQ$C>13=tgUJt_0BJ0n@h0AGqL|m zD==52aZvEAV{{Wt5t1iYo}g-ZXVO5aTHZO_As9(1JnK+sOk$5I>3yY%$gGCuTz1!& z;`C-DG;X#r$l9uwG3Jv92{j|YT#@nUPj5iSKaMP-t}zd{KfVgpYzR?p>)`H+_EC;D zBw>$N@NfTDq!T$(CL+v7HuXQXXVc@z!ZQSv$q-^*j*n}Hn)+phePi;J=@Q*D4h%$F zEbGmZrAcaroem0Wrr8=vtMi>mJSuE)3if-acV$ch`@MoK&eVefr2c-)l|}u{Cuj@9 zV`hm-nL4;Hx&>#_cv(>~X^d%8b|xs;=ukK}g&Ol*2sS#Dw1Q&PWT6yh<&#e7S7EbL z;q5r0$=iOxW@mD5F~lQ9Sp_JS)|*MUge1J`5$te{e`PEnVTVib>I~fyue4U6lo*R^ zY?furgd7?aY#LCokI3Qe5!f`Kr0k|tEU{UZQDR(NqXimQ<*p{&IdYihuvwPm>7y+=@hfpOul|0 lH(PBiF Ano novo, projeto novo. **Uma dica de JS por dia!** + +Com grande entusiasmo, apresento estas dicas diárias de JavaScript curtas e úteis que lhe permitirá melhorar a sua escrita de código. Com menos de 2 minutos a cada dia, você será capaz de ler sobre desempenho, convenções, hacks, questões e todos os itens que o futuro desta linguagem impressionante tem para nós. + +Ao meio-dia, não importa se é fim de semana ou feriado, uma dica será postada e tuitada. + +### Você pode nos ajudar a melhorar? +Por favor, sinta-se à vontade para nos enviar um PR com sua própria dica de JavaScript para ser publicada aqui. +Qualquer melhoria ou sugestão são mais que bem-vindas! +[Clique para ver as instruções](https://github.com/loverajoel/jstips/blob/master/CONTRIBUTING.md) + +### Vamos manter contato + +Há várias maneiras de obter atualização, escolha a sua + +- [Blog Oficial](http://www.jstips.co) +- [Conta Oficial no Twitter](https://twitter.com/tips_js) +- [Hubot](https://github.com/dggriffin/hubot-jstips) +- [js2016.tips](http://js2016.tips/) +- [Hingsir](http://hingsir.com/jstips-site/dist/tips/) +- [Awesomelists](https://awesomelists.top/#/repos/loverajoel/jstips) + +> Não se esqueça de dar estrela no projeto, isto ajudará a promover o projeto! + +### Agradecimentos + +- GIF's => [Maxi Albella](https://dribbble.com/maxialbella) +- Tema do JS Tips => [Marcos Cosimi](https://github.com/markoscc) +- Bandeiras => [Muharrem Senyil](https://dribbble.com/shots/1211759-Free-195-Flat-Flags) \ No newline at end of file diff --git a/pt_BR/index.html b/pt_BR/index.html new file mode 100644 index 00000000..4a05f28a --- /dev/null +++ b/pt_BR/index.html @@ -0,0 +1,4 @@ +--- +layout: home +lang: pt_BR +--- From 3c5e05316417dc0e5686d3ec13e92aae07b7e13e Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Fri, 5 Feb 2016 11:18:31 -0200 Subject: [PATCH 17/27] Editing _config.yml --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 1c393682..df6a4a2c 100644 --- a/_config.yml +++ b/_config.yml @@ -151,7 +151,7 @@ transl: submit_your_tip: txt: Envie sua dica link: https://github.com/loverajoel/jstips/blob/gh-pages/CONTRIBUTING_pt_BR.md - footer_subscribe_message: Subscribe to more awesome daily tips! + footer_subscribe_message: Inscreva-se para mais incríveis dicas diárias! footer_placeholder_subscribe: seu@email.com arrow_prev: Dica anterior arrow_next: Próxima dica From 86eb57a6665cd89cf6bba1c67d09771e89271edc Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Fri, 5 Feb 2016 14:15:58 -0200 Subject: [PATCH 18/27] Improve Nested Conditionals - pt_BR --- .../2015-12-29-insert-item-inside-an-array.md | 6 +- .../2016-01-01-angularjs-digest-vs-apply.md | 14 +-- ...ys-in-children-components-are-important.md | 22 ++--- .../2016-01-03-improve-nested-conditionals.md | 92 +++++++++++++++++++ pt_BR/about.md | 2 +- 5 files changed, 114 insertions(+), 22 deletions(-) create mode 100644 _posts/pt_BR/2016-01-03-improve-nested-conditionals.md diff --git a/_posts/pt_BR/2015-12-29-insert-item-inside-an-array.md b/_posts/pt_BR/2015-12-29-insert-item-inside-an-array.md index 253286c4..7c107db3 100644 --- a/_posts/pt_BR/2015-12-29-insert-item-inside-an-array.md +++ b/_posts/pt_BR/2015-12-29-insert-item-inside-an-array.md @@ -5,14 +5,14 @@ title: Inserir item em um array tip-number: 00 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel -tip-tldr: Inserir um item em um array existente é muito comum diariamente. Você pode adicionar elementos no final de um array usando push, no começo usando unshift ou no meio usando splice. +tip-tldr: Inserir um item em um array existente é uma tarefa muito comum. Você pode adicionar elementos no final de um array usando push, no começo usando unshift ou no meio usando splice. categories: - - pt_br + - pt_BR --- -Inserir um item em um array existente é muito comum diariamente. Você pode adicionar elementos no final de um array usando push, no começo usando unshift ou no meio usando splice. +Inserir um item em um array existente é uma tarefa muito comum. Você pode adicionar elementos no final de um array usando push, no começo usando unshift ou no meio usando splice. Estes são métodos conhecidos, mas não significa que não exista uma forma mais performática. Vamos lá: diff --git a/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md b/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md index c083d604..a0e5afb3 100644 --- a/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md +++ b/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md @@ -5,10 +5,10 @@ title: AngularJs - `$digest` vs `$apply` tip-number: 01 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel -tip-tldr: JavaScript modules e build steps estão ficando numerosos e complicados, mas e boilerplate e novos frameworks? +tip-tldr: Módulos JavaScript e ferramentas de build estão ficando cada vez mais numerosas e complicadas, mas e as receitas de bolo nos novos frameworks? categories: - - pt_br + - pt_BR --- Uma das características mais apreciadas do AngularJs é o two-way data binding. Para fazer este trabalho o AngularJs avalia as mudanças entre o model e a view através de ciclos ( $digest ). Você precisa entender esse conceito para entender como o framework funciona debaixo do capô. @@ -16,14 +16,14 @@ Uma das características mais apreciadas do AngularJs é o two-way data binding. Angular avalia cada observador quando um evento é disparado. Esse é o ciclo conhecido como `$digest`. Algumas vezes você precisa forçar a execução de um novo ciclo manualmente e deve escolher a opção correta pois esta fase é uma das que mais influencia em termos de performance. ### `$apply` -Este método do core permite você iniciar o ciclo digestion explicitamente. Isso significa que todos os observadores são verificados; toda a aplicação inicia o `$digest loop`. Internamente, depois de executar um parâmetro de função opcional, ele chama `$rootScope.$digest();`. +Este método do core permite você iniciar o ciclo digest explicitamente. Isso significa que todos os observadores são verificados; toda a aplicação inicia o `$digest loop`. Internamente, depois de executar um parâmetro de função opcional, ele chama `$rootScope.$digest();`. ### `$digest` -Nesse caso o método `$digest` inicia o ciclo `$digest` para o escopo atual e seu filhos. Você deve notar que os escopos pais não serão verificados e afetados. +Nesse caso o método `$digest` inicia o ciclo `$digest` para o escopo atual e seu filhos. Você deve notar que os escopos pais não serão verificados ou afetados. ### Recomendações -- Use `$apply` ou `$digest` somente quando os eventos DOM do navegador forem provocados fora do AngularJs. -- Passe uma expressão de função para `$apply`, ele tem um mecanismo de tratamento de erros e permite integrar as mudanças no ciclo digest. +- Use `$apply` ou `$digest` somente quando os eventos DOM do navegador forem executados fora do AngularJs. +- Passe uma function expression para `$apply`, ele tem um mecanismo de tratamento de erros e permite integrar as mudanças no ciclo digest. ```javascript $scope.$apply(() => { @@ -31,6 +31,6 @@ $scope.$apply(() => { }); ``` -- Se você só precisa atualizar o escopo atual ou seus filhos, use `$digest`, previnindo um novo ciclo digest para toda a aplicação. O benefício em performance é evidente. +- Se você só precisa atualizar o escopo atual ou seus filhos, use `$digest`, prevenindo um novo ciclo digest para toda a aplicação. O benefício em performance é evidente. - `$apply()` é um processo difícil para a máquina e pode causar problemas de performance quando se tem muito binding. - Se você está usando >AngularJS 1.2.X, use `$evalAsync`, um método do core que irá avaliar a expressão durante o ciclo atual ou o próximo. Isto pode melhorar a performance da aplicação. \ No newline at end of file diff --git a/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md index 20823270..99d9e053 100644 --- a/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md +++ b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md @@ -5,18 +5,18 @@ title: Keys in children components are important tip-number: 02 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel -tip-tldr: The key is an attribute that you must pass to all components created dynamically from an array. It's a unique and constant id that React uses to identify each component in the DOM and to know whether it's a different component or the same one. Using keys ensures that the child component is preserved and not recreated and prevents weird things from happening. +tip-tldr: Key é um atributo que você deve passar para todos os componentes criados dinamicamente a partir de um array. É um id único e constante que o React usa para identificar cada componente no DOM e saber quando é diferente ou o mesmo componente. Usar keys garante que o componente filho é preservado e não recriado prevenindo comportamentos não esperados. categories: - - pt_br + - pt_BR --- -The [key](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children) is an attribute that you must pass to all components created dynamically from an array. It's a unique and constant id that React uses to identify each component in the DOM and to know whether it's a different component or the same one. Using keys ensures that the child component is preserved and not recreated and prevents weird things from happening. +[Key](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children) é um atributo que você deve passar para todos os componentes criados dinamicamente a partir de um array. É um id único e constante que o React usa para identificar cada componente no DOM e saber quando é diferente ou o mesmo componente. Usar keys garante que o componente filho é preservado e não recriado prevenindo comportamentos não esperados. -> Key is not really about performance, it's more about identity (which in turn leads to better performance). Randomly assigned and changing values do not form an identity [Paul O’Shannessy](https://github.com/facebook/react/issues/1342#issuecomment-39230939) +> Key realmente não é sobre performance, é mais sobre identificar (que por sua vez leva a um melhor desempenho). Atribuição aleatória e mudança de valores não formam uma identidade [Paul O’Shannessy](https://github.com/facebook/react/issues/1342#issuecomment-39230939) (tradução literal) -- Use an existing unique value of the object. -- Define the keys in the parent components, not in child components +- Use um valor único existente no objeto. +- Defina as keys no componente pai, não nos componentes filhos. ```javascript //bad @@ -29,14 +29,14 @@ render() { //good ``` -- [Using array index is a bad practice.](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318#.76co046o9) -- `random()` will not work +- [Usar índice de array é uma prática ruim.](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318#.76co046o9) +- `random()` não irá funcionar ```javascript //bad ``` -- You can create your own unique id. Be sure that the method is fast and attach it to your object. -- When the number of children is large or contains expensive components, use keys to improve performance. -- [You must provide the key attribute for all children of ReactCSSTransitionGroup.](http://docs.reactjs-china.com/react/docs/animation.html) \ No newline at end of file +- Você pode criar seu próprio id único. Tenha certeza que o método é rápido e anexe ao seu objeto. +- Quando o número de filhos for grande ou conter uma quantidade expressiva de componentes, use keys para melhorar o desempenho. +- [Você deve fornecer o atributo key para todos os filhos de ReactCSSTransitionGroup.](http://docs.reactjs-china.com/react/docs/animation.html) \ No newline at end of file diff --git a/_posts/pt_BR/2016-01-03-improve-nested-conditionals.md b/_posts/pt_BR/2016-01-03-improve-nested-conditionals.md new file mode 100644 index 00000000..5f0f7256 --- /dev/null +++ b/_posts/pt_BR/2016-01-03-improve-nested-conditionals.md @@ -0,0 +1,92 @@ +--- +layout: post + +title: Melhorar Condicionais Aninhados +tip-number: 03 +tip-username: AlbertoFuente +tip-username-profile: https://github.com/AlbertoFuente +tip-tldr: Como podemos melhorar e tornar mais eficiente a declaração de `if` aninhados em javascript? + +categories: + - pt_BR +--- + +Como podemos melhorar e tornar mais eficiente a declaração de `if` aninhados em javascript? + +```javascript +if (color) { + if (color === 'black') { + printBlackBackground(); + } else if (color === 'red') { + printRedBackground(); + } else if (color === 'blue') { + printBlueBackground(); + } else if (color === 'green') { + printGreenBackground(); + } else { + printYellowBackground(); + } +} +``` + +Uma forma de melhorar declarações de `if` aninhados seria usar `switch`. Embora seja menos verboso e mais ordenado, o uso não é recomendado porque seu debug é muito difícil. [Aqui](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals) o porquê. + +```javascript +switch(color) { + case 'black': + printBlackBackground(); + break; + case 'red': + printRedBackground(); + break; + case 'blue': + printBlueBackground(); + break; + case 'green': + printGreenBackground(); + break; + default: + printYellowBackground(); +} +``` + +Mas e se tivermos uma condicional com várias avaliações em cada declaração? Nesse caso, se quisermos algo menos verboso e mais ordenado, podemos usar o condicional `switch`. +Se passarmos `true` como um parâmetro para o `switch`, ele nos permitirá usar uma condicional em cada caso. + +```javascript +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; +} +``` + +Mas devemos sempre evitar muitas verificações em cada condição e evitar `switch` sempre que possível. Também devemos levar em conta que a forma mais eficiente de fazer isto é usando um `object`. + +```javascript +var colorObj = { + 'black': printBlackBackground, + 'red': printRedBackground, + 'blue': printBlueBackground, + 'green': printGreenBackground, + 'yellow': printYellowBackground +}; + +if (color in colorObj) { + colorObj[color](); +} +``` + +[Aqui](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/) você pode encontrar mais informações sobre isto. diff --git a/pt_BR/about.md b/pt_BR/about.md index 3808c1f5..68788e6c 100644 --- a/pt_BR/about.md +++ b/pt_BR/about.md @@ -7,7 +7,7 @@ lang: pt_BR > Ano novo, projeto novo. **Uma dica de JS por dia!** -Com grande entusiasmo, apresento estas dicas diárias de JavaScript curtas e úteis que lhe permitirá melhorar a sua escrita de código. Com menos de 2 minutos a cada dia, você será capaz de ler sobre desempenho, convenções, hacks, questões e todos os itens que o futuro desta linguagem impressionante tem para nós. +Com grande entusiasmo, apresento diariamente estas dicas curtas e úteis sobre JavaScript que lhe permitirão melhorar a escrita do seu código. Com menos de 2 minutos a cada dia, você será capaz de ler sobre desempenho, convenções, hacks e todos os itens que o futuro desta linguagem impressionante tem para nós. Ao meio-dia, não importa se é fim de semana ou feriado, uma dica será postada e tuitada. From 08d7c33eea30197bf0fff792a90c1507727973fe Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Fri, 12 Feb 2016 12:35:21 -0200 Subject: [PATCH 19/27] Translate to Portuguese_BR --- .../2016-01-01-angularjs-digest-vs-apply.md | 6 +- ...ys-in-children-components-are-important.md | 8 +- .../2016-01-03-improve-nested-conditionals.md | 76 +++++++++---------- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md b/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md index a0e5afb3..c46dc965 100644 --- a/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md +++ b/_posts/pt_BR/2016-01-01-angularjs-digest-vs-apply.md @@ -13,10 +13,10 @@ categories: Uma das características mais apreciadas do AngularJs é o two-way data binding. Para fazer este trabalho o AngularJs avalia as mudanças entre o model e a view através de ciclos ( $digest ). Você precisa entender esse conceito para entender como o framework funciona debaixo do capô. -Angular avalia cada observador quando um evento é disparado. Esse é o ciclo conhecido como `$digest`. Algumas vezes você precisa forçar a execução de um novo ciclo manualmente e deve escolher a opção correta pois esta fase é uma das que mais influencia em termos de performance. +Angular avalia cada watcher quando um evento é disparado. Esse é o ciclo conhecido como `$digest`. Algumas vezes você precisa forçar a execução de um novo ciclo manualmente e deve escolher a opção correta pois esta fase é uma das que mais influencia em termos de performance. ### `$apply` -Este método do core permite você iniciar o ciclo digest explicitamente. Isso significa que todos os observadores são verificados; toda a aplicação inicia o `$digest loop`. Internamente, depois de executar um parâmetro de função opcional, ele chama `$rootScope.$digest();`. +Este método do core permite você iniciar o ciclo digest explicitamente. Isso significa que todos os watchers são verificados; toda a aplicação inicia o `$digest loop`. Internamente, depois de executar um parâmetro de função opcional, ele chama `$rootScope.$digest();`. ### `$digest` Nesse caso o método `$digest` inicia o ciclo `$digest` para o escopo atual e seu filhos. Você deve notar que os escopos pais não serão verificados ou afetados. @@ -32,5 +32,5 @@ $scope.$apply(() => { ``` - Se você só precisa atualizar o escopo atual ou seus filhos, use `$digest`, prevenindo um novo ciclo digest para toda a aplicação. O benefício em performance é evidente. -- `$apply()` é um processo difícil para a máquina e pode causar problemas de performance quando se tem muito binding. +- `$apply()` é um processo lento para a máquina e pode causar problemas de performance quando se tem muitos bindings. - Se você está usando >AngularJS 1.2.X, use `$evalAsync`, um método do core que irá avaliar a expressão durante o ciclo atual ou o próximo. Isto pode melhorar a performance da aplicação. \ No newline at end of file diff --git a/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md index 99d9e053..7b5ca9d4 100644 --- a/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md +++ b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md @@ -19,24 +19,24 @@ categories: - Defina as keys no componente pai, não nos componentes filhos. ```javascript -//bad +//ruim ... render() {
{{item.name}}
} ... -//good +//bom ``` - [Usar índice de array é uma prática ruim.](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318#.76co046o9) - `random()` não irá funcionar ```javascript -//bad +//ruim ``` - Você pode criar seu próprio id único. Tenha certeza que o método é rápido e anexe ao seu objeto. -- Quando o número de filhos for grande ou conter uma quantidade expressiva de componentes, use keys para melhorar o desempenho. +- Quando o número de filhos for grande ou conter muitos componentes, use keys para melhorar o desempenho. - [Você deve fornecer o atributo key para todos os filhos de ReactCSSTransitionGroup.](http://docs.reactjs-china.com/react/docs/animation.html) \ No newline at end of file diff --git a/_posts/pt_BR/2016-01-03-improve-nested-conditionals.md b/_posts/pt_BR/2016-01-03-improve-nested-conditionals.md index 5f0f7256..c906ea52 100644 --- a/_posts/pt_BR/2016-01-03-improve-nested-conditionals.md +++ b/_posts/pt_BR/2016-01-03-improve-nested-conditionals.md @@ -14,17 +14,17 @@ categories: Como podemos melhorar e tornar mais eficiente a declaração de `if` aninhados em javascript? ```javascript -if (color) { - if (color === 'black') { - printBlackBackground(); - } else if (color === 'red') { - printRedBackground(); - } else if (color === 'blue') { - printBlueBackground(); - } else if (color === 'green') { - printGreenBackground(); +if (cor) { + if (cor === 'preto') { + imprimirPreto(); + } else if (cor === 'vermelho') { + imprimirVermelho(); + } else if (cor === 'azul') { + imprimirAzul(); + } else if (cor === 'verde') { + imprimirVerde(); } else { - printYellowBackground(); + imprimirAmarelo(); } } ``` @@ -32,21 +32,21 @@ if (color) { Uma forma de melhorar declarações de `if` aninhados seria usar `switch`. Embora seja menos verboso e mais ordenado, o uso não é recomendado porque seu debug é muito difícil. [Aqui](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals) o porquê. ```javascript -switch(color) { - case 'black': - printBlackBackground(); +switch(cor) { + case 'preto': + imprimirPreto(); break; - case 'red': - printRedBackground(); + case 'vermelho': + imprimirVermelho(); break; - case 'blue': - printBlueBackground(); + case 'azul': + imprimirAzul(); break; - case 'green': - printGreenBackground(); + case 'verde': + imprimirVerde(); break; default: - printYellowBackground(); + imprimirAmarelo(); } ``` @@ -55,20 +55,20 @@ Se passarmos `true` como um parâmetro para o `switch`, ele nos permitirá usar ```javascript switch(true) { - case (typeof color === 'string' && color === 'black'): - printBlackBackground(); + case (typeof cor === 'string' && cor === 'preto'): + imprimirPreto(); break; - case (typeof color === 'string' && color === 'red'): - printRedBackground(); + case (typeof cor === 'string' && cor === 'vermelho'): + imprimirVermelho(); break; - case (typeof color === 'string' && color === 'blue'): - printBlueBackground(); + case (typeof cor === 'string' && cor === 'azul'): + imprimirAzul(); break; - case (typeof color === 'string' && color === 'green'): - printGreenBackground(); + case (typeof cor === 'string' && cor === 'verde'): + imprimirVerde(); break; - case (typeof color === 'string' && color === 'yellow'): - printYellowBackground(); + case (typeof cor === 'string' && cor === 'amarelo'): + imprimirAmarelo(); break; } ``` @@ -76,16 +76,16 @@ switch(true) { Mas devemos sempre evitar muitas verificações em cada condição e evitar `switch` sempre que possível. Também devemos levar em conta que a forma mais eficiente de fazer isto é usando um `object`. ```javascript -var colorObj = { - 'black': printBlackBackground, - 'red': printRedBackground, - 'blue': printBlueBackground, - 'green': printGreenBackground, - 'yellow': printYellowBackground +var corObj = { + 'preto': imprimirPreto, + 'vermelho': imprimirVermelho, + 'azul': imprimirAzul, + 'verde': imprimirVerde, + 'amarelo': imprimirAmarelo }; -if (color in colorObj) { - colorObj[color](); +if (cor in corObj) { + corObj[cor](); } ``` From 9d67b2a6cdb81504246738cbc64ee785c9f3fdea Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Tue, 16 Feb 2016 11:57:36 -0200 Subject: [PATCH 20/27] Translate to Portuguese_BR --- ...ys-in-children-components-are-important.md | 2 +- ...orting-strings-with-accented-characters.md | 66 +++++++++++++++++++ ...-differences-between-undefined-and-null.md | 39 +++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 _posts/pt_BR/2016-01-04-sorting-strings-with-accented-characters.md create mode 100644 _posts/pt_BR/2016-01-05-differences-between-undefined-and-null.md diff --git a/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md index 7b5ca9d4..37881e16 100644 --- a/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md +++ b/_posts/pt_BR/2016-01-02-keys-in-children-components-are-important.md @@ -1,7 +1,7 @@ --- layout: post -title: Keys in children components are important +title: Keys em componentes filhos são importantes tip-number: 02 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel diff --git a/_posts/pt_BR/2016-01-04-sorting-strings-with-accented-characters.md b/_posts/pt_BR/2016-01-04-sorting-strings-with-accented-characters.md new file mode 100644 index 00000000..41314244 --- /dev/null +++ b/_posts/pt_BR/2016-01-04-sorting-strings-with-accented-characters.md @@ -0,0 +1,66 @@ +--- +layout: post + +title: Ordenando strings com caracteres acentuados +tip-number: 04 +tip-username: loverajoel +tip-username-profile: https://github.com/loverajoel +tip-tldr: Javascript tem o método nativo **sort** que permite ordenar arrays. Um simples `array.sort()` irá tratar cada item do array como uma string e ordená-los alfabeticamente. Mas quando tentamos ordenar um array com caracteres fora da tabela ASCII obtemos um resultado inesperado. + +categories: + - pt_BR +--- + +Javascript tem o método nativo **[sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)** que permite ordenar arrays. Um simples `array.sort()` irá tratar cada item do array como uma string e ordená-los alfabeticamente. Você também pode utilizar sua [própria função de ordenação](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters). + +```javascript +['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); +// ["Buenos Aires", "Mumbai", "New York", "Shanghai"] +``` + +Mas quando tentamos ordenar um array com caracteres fora da tabela ASCII como este `['é', 'a', 'ú', 'c']`, obtemos um resultado inesperado `['c', 'e', 'á', 'ú']`. Isto acontece porque o sort funciona apenas com o idioma inglês. + +Veja o próximo exemplo: + +```javascript +// Spanish +['único','árbol', 'cosas', 'fútbol'].sort(); +// ["cosas", "fútbol", "árbol", "único"] // ordem ruim + +// German +['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); +// ["Wann", "Woche", "wäre", "wöchentlich"] // ordem ruim +``` + +Felizmente, existem duas formas de evitar este comportamento: [localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) e [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator) graças a ECMAScript Internationalization API. + +> Ambos os métodos possuem seus próprios parâmetro personalizados, para que funcionem corretamente. + +### Usando `localeCompare()` + +```javascript +['ú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"] +``` + +### Usando `Intl.Collator()` + +```javascript +['ú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"] +``` + +- Para cada método você pode customizar a localização. +- De acordo com o [Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance) Intl.Collator é mais rápido em comparações com uma grande quantidade de strings. + +Portanto, quando estiver trabalhando com strings em outro idioma que não seja o inglês, lembre-se de usar este método para evitar uma ordenação incorreta. \ No newline at end of file diff --git a/_posts/pt_BR/2016-01-05-differences-between-undefined-and-null.md b/_posts/pt_BR/2016-01-05-differences-between-undefined-and-null.md new file mode 100644 index 00000000..9819ab9b --- /dev/null +++ b/_posts/pt_BR/2016-01-05-differences-between-undefined-and-null.md @@ -0,0 +1,39 @@ +--- +layout: post + +title: Diferenças entre `undefined` e `null` +tip-number: 05 +tip-username: loverajoel +tip-username-profile: https://github.com/loverajoel +tip-tldr: Entendendo as diferenças entre `undefined` e `null`. + +categories: + - pt_BR +--- + +- `undefined` significa que a variável não foi declarada ou foi declarada mas ainda não foi atribuído um valor +- `null` é uma atribuição que significa "sem valor" +- Javascript seta variáveis com valor não atribuído como `undefined` por padrão +- Javascript nunca seta um valor como `null`. Ele é usado por programadores para indicar que uma `var` não tem valor. +- `undefined` não é válido em JSON enquanto `null` é +- `undefined` typeof é `undefined` +- `null` typeof é um `object`. [Por quê?](http://www.2ality.com/2013/10/typeof-null.html) +- Ambos são primitivos +- Ambos são [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) + (`Boolean(undefined) // false`, `Boolean(null) // false`) +- Você pode saber se uma variável é [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined, + ```javascript + typeof variable === "undefined" +``` +- Você pode checar se uma variável é [null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null) + + ```javascript + variable === null +``` +- O **operador de igualdade** considera-os iguais, mas o **operador de igualdade estrita** não + + ```javascript + null == undefined // true + + null === undefined // false +``` \ No newline at end of file From 5606effd7baea33e9becd3694a4cff87cfa734fa Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Tue, 16 Feb 2016 16:42:02 -0200 Subject: [PATCH 21/27] Translate to Portuguese_BR --- ...-method-for-arrays-and-a-single-element.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 _posts/pt_BR/2016-01-06-writing-a-single-method-for-arrays-and-a-single-element.md diff --git a/_posts/pt_BR/2016-01-06-writing-a-single-method-for-arrays-and-a-single-element.md b/_posts/pt_BR/2016-01-06-writing-a-single-method-for-arrays-and-a-single-element.md new file mode 100644 index 00000000..e136933c --- /dev/null +++ b/_posts/pt_BR/2016-01-06-writing-a-single-method-for-arrays-and-a-single-element.md @@ -0,0 +1,36 @@ +--- +layout: post + +title: Escrevendo um único método tanto para arrays quanto para elementos únicos +tip-number: 06 +tip-username: mattfxyz +tip-username-profile: https://twitter.com/mattfxyz +tip-tldr: Ao invés de escrever um método para manipular array e outro para elementos únicos como parâmetro, escreva uma função que possa lidar com ambos. É parecido como algumas funções do jQuery funcionam (`css` modificará tudo que combinar com o seletor). + +categories: + - pt_BR +--- + +Ao invés de escrever um método para manipular array e outro para elementos únicos como parâmetro, escreva uma função que possa lidar com ambos. É parecido como algumas funções do jQuery funcionam (`css` modificará tudo que combinar com o seletor). + +Você tem apenas que concatenar tudo em um array. `Array.concat` aceitará um array ou um elemento único. + +```javascript +function imprimirMaiusculas(palavras) { + var elements = [].concat(palavras); + for (var i = 0; i < elements.length; i++) { + console.log(elements[i].toUpperCase()); + } +} +``` + +`imprimirMaiusculas` agora está pronta para aceitar um único item ou um array de itens como parâmetro. + +```javascript +imprimirMaiusculas("cacto"); +// => CACTUS +imprimirMaiusculas(["cacto", "urso", "batata"]); +// => CACTUS +// BEAR +// POTATO +``` From 86a96170131fd294263580d994f25b65bd1b8249 Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Thu, 25 Feb 2016 12:22:07 -0300 Subject: [PATCH 22/27] Translate to Portuguese_BR --- ...1-08-converting-a-node-list-to-an-array.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 _posts/pt_BR/2016-01-08-converting-a-node-list-to-an-array.md diff --git a/_posts/pt_BR/2016-01-08-converting-a-node-list-to-an-array.md b/_posts/pt_BR/2016-01-08-converting-a-node-list-to-an-array.md new file mode 100644 index 00000000..654d8165 --- /dev/null +++ b/_posts/pt_BR/2016-01-08-converting-a-node-list-to-an-array.md @@ -0,0 +1,43 @@ +--- +layout: post + +title: Convertendo uma lista de nós em array +tip-number: 08 +tip-username: Tevko +tip-username-profile: https://twitter.com/tevko +tip-tldr: Aqui vai uma maneira rápida, segura e reutilizável para converter uma lista de nós em um array de elementos do DOM. + +categories: + - pt_BR +--- + +O método `querySelectorAll` retorna um objeto array-like chamado de lista de nós. Estas estruturas de dados são tratadas como "Array-like" porque elas se parecem com um array, mas não podem ser usadas com métodos de array como `map` e `forEach`. Aqui vai uma maneira rápida, segura e reutilizável para converter uma lista de nós em um array de elementos do DOM: + +```javascript +const nodelist = document.querySelectorAll('div'); +const nodelistToArray = Array.apply(null, nodelist); + +// e então... + +nodelistToArray.forEach(...); +nodelistToArray.map(...); +nodelistToArray.slice(...); + +//etc... +``` + +O método `apply` é usado para passar um array de argumentos para uma função com um determinado valor de `this`. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) diz que o `apply` recebe um objeto array-like, que é exatamente o que o `querySelectorAll` retorna. Uma vez que não precisamos especificar um valor para this no contexto da função, passamos `null` ou `0`. O resultado é uma array de elementos do DOM que contém todos os métodos de array disponíveis. + +Se estiver usando ES2015 você pode usar o [operador spread `...`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) + +```js +const nodelist = [...document.querySelectorAll('div')]; // returns a real array + +//later on .. + +nodelist.forEach(...); +nodelist.map(...); +nodelist.slice(...); + +//etc... +``` \ No newline at end of file From 4f9f9f5e013976530f68efe02bb1904e28111fdb Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Fri, 26 Feb 2016 14:57:18 -0300 Subject: [PATCH 23/27] Translate to Portuguese_BR --- _posts/pt_BR/2016-01-09-template-strings.md | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 _posts/pt_BR/2016-01-09-template-strings.md diff --git a/_posts/pt_BR/2016-01-09-template-strings.md b/_posts/pt_BR/2016-01-09-template-strings.md new file mode 100644 index 00000000..5f4b4a4e --- /dev/null +++ b/_posts/pt_BR/2016-01-09-template-strings.md @@ -0,0 +1,39 @@ +--- +layout: post + +title: Strings template +tip-number: 09 +tip-username: JakeRawr +tip-username-profile: https://github.com/JakeRawr +tip-tldr: A partir do ES6, o JS tem strings template como uma alternativa às citações clássicas em strings. + +categories: + - pt_BR +--- + +A partir do ES6, o JS tem strings template como uma alternativa ao clássico de citações em strings. + +Ex: +String normal + +```javascript +var nome = 'Jake'; +var sobrenome = 'Rawr'; +console.log('Meu nome é ' + nome + ' ' + sobrenome); +// Meu nome é Jake Rawr +``` +Template String + +```javascript +var nome = 'Jake'; +var sobrenome = 'Rawr'; +console.log(`Meu nome é ${nome} ${sobrenome}`); +// Meu nome é Jake Rawr +``` + +Você pode utilizar strings multilinhas sem `\n` e lógica simples (ex 2+3) dentro de `${}` em strings templates. + +Também é possível modificar a saída de strings template usando uma função; chama-se [tagged template strings] +(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings#Tagged_template_strings), veja os exemplos de uso. + +Você também pode querer [ler para entender](https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2) mais sobre strings template. \ No newline at end of file From 44c7c8906058326a87c2ac54aa2d2e1bafad1dbf Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Tue, 1 Mar 2016 16:16:27 -0300 Subject: [PATCH 24/27] Translate to Portuguese_BR --- ...1-10-check-if-a-property-is-in-a-object.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 _posts/pt_BR/2016-01-10-check-if-a-property-is-in-a-object.md diff --git a/_posts/pt_BR/2016-01-10-check-if-a-property-is-in-a-object.md b/_posts/pt_BR/2016-01-10-check-if-a-property-is-in-a-object.md new file mode 100644 index 00000000..303aff13 --- /dev/null +++ b/_posts/pt_BR/2016-01-10-check-if-a-property-is-in-a-object.md @@ -0,0 +1,60 @@ +--- +layout: post + +title: Checar se uma propriedade está em um objeto +tip-number: 10 +tip-username: loverajoel +tip-username-profile: https://www.twitter.com/loverajoel +tip-tldr: Estas são as formas de checar se uma propriedade está presente em um objeto. + +categories: + - pt_BR +--- + +Quando você tem de checar se uma propriedade está presente em um [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects), você provavelmente faz algo assim: + +```javascript +var meuObjeto = { + nome: '@tips_js' +}; + +if (meuObjeto.nome) { ... } + +``` + +Isto funciona, mas você deve saber que há duas formas nativas para isto, o [operador `in`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in) e o [`Object.hasOwnProperty`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty). Todo objeto descendente de `Object` pode ser checados das duas maneiras. + +### Entenda a grande diferença + +```javascript +var meuObjeto = { + nome: '@tips_js' +}; + +meuObjeto.hasOwnProperty('nome'); // true +'nome' in meuObjeto; // true + +meuObjeto.hasOwnProperty('valueOf'); // false, valueOf é herdado de protótipo +'valueOf' in meuObjeto; // true + +``` + +A diferença está na profundidade em que cada uma checa a propriedade. Em outras palavras, `hasOwnProperty` somente retornará true se a propriedade estiver ligada diretamente à este objeto. Já para o operador `in` não importa se a propriedade foi criada no objeto ou herdada de um protótipo. + +Outro exemplo: + +```javascript +var minhaFuncao = function() { + this.nome = '@tips_js'; +}; +minhaFuncao.prototype.idade = '10 days'; + +var usuario = new minhaFuncao(); + +usuario.hasOwnProperty('nome'); // true +usuario.hasOwnProperty('idade'); // false, porque idade vem de um protótipo +``` + +Confira os [exemplos em tempo real aqui](https://jsbin.com/tecoqa/edit?js,console)! + +Também recomendo que leia [esta discussão](https://github.com/loverajoel/jstips/issues/62) sobre erros comuns quando se checa uma propriedade existente em um objeto. \ No newline at end of file From 6b4972a611b600283ac11fb183ef314e6f44d1fe Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Mon, 14 Mar 2016 14:03:25 -0300 Subject: [PATCH 25/27] Translate to Portuguese_BR --- _posts/pt_BR/2016-01-11-hoisting.md | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 _posts/pt_BR/2016-01-11-hoisting.md diff --git a/_posts/pt_BR/2016-01-11-hoisting.md b/_posts/pt_BR/2016-01-11-hoisting.md new file mode 100644 index 00000000..2507cc29 --- /dev/null +++ b/_posts/pt_BR/2016-01-11-hoisting.md @@ -0,0 +1,52 @@ +--- +layout: post + +title: Hoisting (Içamento) +tip-number: 11 +tip-username: squizzleflip +tip-username-profile: https://twitter.com/squizzleflip +tip-tldr: Entender hoisting (içamento) irá te ajudar a organizar o escopo de funções. + +categories: + - pt_BR +--- + +Entender [hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) irá te ajudar a organizar o escopo de funções. Lembre-se, declarações de variáveis e definições de funções são içadas para o topo. Definições de variáveis não, mesmo se você declarar e definir uma variável na mesma linha. A **declaração** de uma variável permite que o sistema saiba que ela existe enquanto a **definição** lhe atribui um valor. + + +```javascript +function fazerAlgo() { + // ReferenceError: naoDeclarada is not defined + console.log(naoDeclarada); + + // Saída: undefined + console.log(definidaDepois); + var definidaDepois; + + definidaDepois = 'Eu estou definida!' + // Saída: 'Eu estou definida!' + console.log(definidaDepois); + + // Saída: undefined + console.log(definidaSimultaneamente); + var definidaSimultaneamente = 'Eu estou definida!' + // Saída: 'Eu estou definida!' + console.log(definidaSimultaneamente); + + // Saída: 'Eu fiz isto!' + fazerOutraCoisa(); + + function fazerOutraCoisa(){ + console.log('Eu fiz isto!'); + } + + // TypeError: undefined is not a function + funcaoVar(); + + var funcaoVar = function(){ + console.log('Eu fiz isto!'); + } +} +``` + +Para tornar as coisas fáceis de se ler, declare todas variáveis no topo do escopo da sua função para que fique claro de qual escopo elas estão vindo. Defina suas variáveis antes de precisar usá-las. Defina suas funções no final do seu escopo para que fiquem fora do seu caminho. \ No newline at end of file From 82e99f95ea2825ff3bf3ffdb0a99ec4d657cc9e2 Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Mon, 14 Mar 2016 14:41:57 -0300 Subject: [PATCH 26/27] Translate to Portuguese_BR --- ...domandatory-parameters-in-es6-functions.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 _posts/pt_BR/2016-01-12-pseudomandatory-parameters-in-es6-functions.md diff --git a/_posts/pt_BR/2016-01-12-pseudomandatory-parameters-in-es6-functions.md b/_posts/pt_BR/2016-01-12-pseudomandatory-parameters-in-es6-functions.md new file mode 100644 index 00000000..e3c9f880 --- /dev/null +++ b/_posts/pt_BR/2016-01-12-pseudomandatory-parameters-in-es6-functions.md @@ -0,0 +1,27 @@ +--- +layout: post + +title: Parâmetros pseudo obrigatórios em funções ES6 +tip-number: 12 +tip-username: Avraam Mavridis +tip-username-profile: https://github.com/AvraamMavridis +tip-tldr: Em muitas linguages de programação os parâmetros de uma função são obrigatórios por padrão e o desenvolvedor tem que definir explicitamente quando um parâmetro é opcional. + +categories: + - pt_BR +--- + +Em muitas linguages de programação os parâmetros de uma função são obrigatórios por padrão e o desenvolvedor tem que definir explicitamente quando um parâmetro é opcional. No Javascript, todo parâmentro é opcional, mas podemos mudar este comportamento sem mexer no corpo atual da função, tirando vantagem do [**valor padrão para parâmetros em ES6**](http://exploringjs.com/es6/ch_parameter-handling.html#sec_parameter-default-values). + +```javascript +const _erro = function( mensagem ){ + throw new Error( mensagem ); +} + +const pegaSoma = (a = _erro('a não foi definido'), b = _erro('b não foi definido')) => a + b + +pegaSoma( 10 ) // mostra Erro, b não foi definido +pegaSoma( undefined, 10 ) // mostra Erro, a não foi definido + ``` + +`_err ` é uma função que lança um Error imediatamente. Se nenhum valor é passado para algum dos parâmetros, o valor padrão será usado, `_err ` será chamado e um Error será lançado. Veja mais exemplos do **parâmetro padrão** em [Mozilla's Developer Network](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/default_parameters). \ No newline at end of file From 8322e7fa14c34a9e384c6b5109f38333f4b1ffb6 Mon Sep 17 00:00:00 2001 From: Heverton Castro Date: Mon, 14 Mar 2016 16:11:07 -0300 Subject: [PATCH 27/27] Translate to Portuguese_BR --- ...asure-performance-of-a-javascript-block.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 _posts/pt_BR/2016-01-13-tip-to-measure-performance-of-a-javascript-block.md diff --git a/_posts/pt_BR/2016-01-13-tip-to-measure-performance-of-a-javascript-block.md b/_posts/pt_BR/2016-01-13-tip-to-measure-performance-of-a-javascript-block.md new file mode 100644 index 00000000..f59f7aaf --- /dev/null +++ b/_posts/pt_BR/2016-01-13-tip-to-measure-performance-of-a-javascript-block.md @@ -0,0 +1,32 @@ +--- +layout: post + +title: Dica para medir performance de um bloco de javascript +tip-number: 13 +tip-username: manmadareddy +tip-username-profile: https://twitter.com/manmadareddy +tip-tldr: Para medir rapidamente a performance de um bloco de javascript, nós podemos usar as funções de console, como `console.time(label)` e `console.timeEnd(label)` + +categories: + - pt_BR +--- + +Para medir rapidamente a performance de um bloco de javascript, nós podemos usar as funções de console, como [`console.time(label)`](https://developer.chrome.com/devtools/docs/console-api#consoletimelabel) e [`console.timeEnd(label)`](https://developer.chrome.com/devtools/docs/console-api#consoletimeendlabel) + +```javascript +console.time("Inicialização do array"); +var arr = new Array(100), + len = arr.length, + i; + +for (i = 0; i < len; i++) { + arr[i] = new Object(); +}; +console.timeEnd("Inicialização do array"); // Saída: Inicialização do array: 0.711ms +``` + +Mais informações: +[Console object](https://github.com/DeveloperToolsWG/console-object), +[Javascript benchmarking](https://mathiasbynens.be/notes/javascript-benchmarking) + +Demonstração: [jsfiddle](https://jsfiddle.net/meottb62/) - [codepen](http://codepen.io/anon/pen/JGJPoa) (saída no console do navegador) \ No newline at end of file