Giter VIP home page Giter VIP logo

javascript-patterns's Introduction

javascript-patterns's People

Contributors

alexjeng avatar billyeh avatar brunocoelho avatar cbonnissent avatar charlescao avatar chuanxshi avatar davej avatar devinrhode2 avatar dimitrk avatar eddiemoore avatar eliperelman avatar ericgeurts avatar glebinsky avatar grom-s avatar hello71 avatar hitautodestruct avatar incalite avatar jakemichaeldrew avatar johnpolacek avatar karasatishkumar avatar kybernetikos avatar nhducit avatar norlin avatar okami- avatar petekeller2 avatar sayll avatar stembrain avatar stevenblack avatar trico avatar vitkarpov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

javascript-patterns's Issues

When this conditional expression can be better than anything else?

Hello guys.

In this conditional pattern doc, you say:

Using the normal pattern will generally outperform the regex (alternative method 1) in a loop, [...]"

Then I made a little test – still doubtful, but can give us an idea: Conditional Expressions Difference.

I really was expecting that regex would be faster/better outside a loop – as I outputted on the alert() – but it doesn't seem to happen.

Yes, I know – jsPerf isn't the most trustful way of performance rating, but as I said, it can give us a starting point.

So, what does "outperform" really means?

addEventListener and attachEvent check

is somewhat "wrong", I wouldn't nitpick but this is supposed to be about best practices :p

Anyway, it mentions that the typeof check is better, which it's really not, you're doing little more than the example
above it, if anything you should do 'function' == typeof in that case, but even then I wouldn't call that best practice
unless you're paranoid

Use `hasOwnProperty` in the memoization pattern

  var myFunc = function (param) {
    if (!myFunc.cache[param]) {
      var result = {};
      // ... expsensive operation ...
      myFunc.cache[param] = result;
    }
    return myFunc.cache[param];
  };

If param is e.g. "toString" this will cause problems.

({})['toString'] // function toString() { [native code] }

The solution is to use hasOwnProperty.

Function declarations -- antipattern?

Here you mention that function declarations are an anti-pattern. However you don't substantiate this. Do you say this because FunctionDeclaration hoisting is sometimes considered confusing?

I don't believe Function Declarations are an anti-pattern at all. In fact they're favourable in many cases --

  1. for debuggability
  2. for semantics
  3. sometimes hoisting is useful (declaring static constants above a FuncDec

#5

#5

Sent via Hubroid

memoization using multiple argument as JSON-key

I was looking at the memoization patterns and specifically 'preferred method 2' (multiple arguments using JSON stringify) and noticed a possible issue:

var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)),

Maybe it should mention that this will only work correctly for primitive (and Array) arguments, since the order in which properties of Objects are enumerated is undetermined and can even change between enumerations. (a JSON encoder that sorts the keys won't have this issue).

Take for example this object:

{a:1, b:2}

Could on execution result in theseJSONs and so miss the cache.
"{'a':1, 'b':2}"
"{'b':2, 'a':1}"

Patterns not consistently used

In explanations for certain patterns, other anti-patterns are often used. I.E. in the explanation code for the "Single var pattern", the patterns for "Function Declarations" and "Access to the Global Object" are both ignored:

function updateElement() {
var el = document.getElementById("result")
, style = el.style;
// do something with el and style...
}

Shouldn't all patterns be used consistently, with only changing the focus example by example?

Is it an antipattern?

Hi guys. I've watched all of yours topics about patterns and antipatterns. Nice job! But, I have comments and questions for some topics. I think, some of your patterns is not good. So let's check.

regular-expression-literal.html
Using RegExp constructor can't be antipattern because sometimes we need to create regular expressions dynamically with some input data. For example:

//I know what this example is trivial and not good but it's only for example
function hasClass(element, className){
    var regular = new RegExp('(^|\\s)' + className + '(\\s|$)', 'g');
    return regular.test(element.className);
}

enforcing-new.html
Let's be more logical. If I write functionName() I want to call some function. If I write new FunctionName() I want to create some object. Using your pattern I can create new object even when I call function. But for what? Because we can save 4 symbols and it can minimize file size? Huh, it make me laugh. I think logic of code is more important than file size.

avoiding-implied-typecasting.html
I think, one of antipattern in JavaScript is comparison with true/false/null/undefined. Always we can avoid this comparison using next construction:

var zero = false, n = null;
if(!zero){    //instead of zero === false
}
if(!some){    //instead of some === undefined or typeof some === 'undefined'
}
if(!n){    //instead of n === null
}

for-loops.html
http://jsperf.com/for-loop-caching As you can see there is no difference. And when we cache array size we create new variable. I think it's not useful variable.

for-in-loops.html
For the last example. Why I should save link to Object.prototype.hasOwnProperty when all objects are have this method?

function-declarations.html
This topic is real antipattern. Why I can't use simple function declaration?
The difference between function someFunc(){} and var someFunc = function(){} is the moment when they are created. Simple function declaration will create function before script executing. Declaration function like new variable will create function when script will be working. And all of this functions will be local. So which variant is antipattern? But, simple function declaration can be used only in global scope or first IIFE. Otherwise local function will be created in advance even if you don't call the desired function.

conditionals.html
I think, construction bool && boo() is not logical because it's not expression, it's condition. And condition can't be used like expression.

if (({foo:1, bar:1})[type]) {}

Create new object for one condition? WTF?

revelation.html and module.html
Why you use comparison object with "[object Array]" to indicate arrays when you can use object instanceof Array or object.constructor === Array.

klass.html
Classes in JavaScript... Again...
Why people can't understand prototypal-based programming and use it instead of this ugly classes? Why all prefer to use classical OOP?
First of all, classes are data types. In JavaScript we work with objects and we have only some primitive types like: number, string, boolean, function. We can't create our personal type. We can create some objects with the same properties.
Secondly, classes unites data and method to work with this data. Constructors in JavaScript do this too. Classical OOP was complicated by a variety of ways to create a class. And, when we create arcitecture of our application one of the main problem can be "Oh, in this class I can use virtual method. Or I should use composite pattern? Hmm...."
"There should be one — and preferably only one — obvious way to do it." (The Zen of Python)
In JavaScript we have only one way to describe objects. We create a function which will be a constructor. Then we can add some properties to prototype object (which placed in our constructor). All properties in prototype are common to all instances of our constructor. That's all. It's realy easy.

I hope you will read all this comments and understand my engilsh :)

Best regards,
Alexey Raspopov

Better jQuery Pattern Append

On https://github.com/shichuan/javascript-patterns/blob/master/jquery-patterns/append.html there's a slight consistency error with your other patterns. It is recomended to use array.push() and then join it instead of appending string over and over

So, instead of

var myhtml = '';
$.each(reallyLongArray, function (count, item) {
        myhtml += '<li>' + item + '</li>';
});
$('#ballers').html(myhtml);

Should be

var myHtml = [];
$.each(reallyLongArray, function(count, item) {
    myHtml.push('<li>' + item + '</li>');
});
$('#ballers').html(myHtml.join(''));

Clean up jQuery selector cache sample

The sample for jQuery selector cache, "using selector cache to avoid requery" is a little misleading; in the following code example, although the .photo element could be cached, if the user never clicks the list item, the .photo query will never happen. A better example would be with a window scroll event, like the reference suggests.

                        // antipattern
            $('.list-item').click(function () {
                $('.photo').hide();
            });


            // preferred
            var photo = $('.photo');
            $('.list-item').click(function () {
                photo.hide();
            });

New method declaration convention

I've come up with a really good convention for naming methods:

person.getData = function person_getData() {
};

We prepend with person_ so that the function name is unique from the identifier, avoiding errors in IE.

It also tells us EXACTLY what function we're dealing with in a stack trace.

@shichuan probably best to let you update the codebase with this new convention; if you approve. For a javascript error dashboard this will prove rather useful

jquery-patterns / window-scroll-event.html

The whole point of not doing much in the scroll event handler is because it degrades performance, but there's no reason to have a constant timer running. You should be running it only when the user starts scrolling:

var scrollTimer;
$(window).scroll(function() {
    scrollTimer && clearTimeout(scrollTimer);
    scrollTimer = setTimeout(function() {
        // Check your page position and then
        // Load in more results
        // Whatever else...
    }, 250);
});

would like to see explanations or references

Beautiful work!

I wish some of the pattern examples had explanations or links to references. For example, in global_selector.js, it would be helpful to see an explanation for why one expression is better than another. Is our optimization criteria for this case performance or clarity?

Namespace

Why do we use

var MYAPP = MYAPP || {};

and not a singleton pattern?

Define "trickyness" in for-loop pattern

On line 35 of the for-loop pattern the following comment appears.

// optimization 3 - substitute i++withi = i + 1 ori += 1 to avoid excessive trickiness

Could you elaborate on "excessive trickiness"?

Get a maintainer

You have too many issues and they seem to be piling up. Maintainers are awesome -- they can merge in reasonable PRs, etc. This site has too many views for it not to be maintained.

Validity of Find over context in jquery

regarding https://github.com/shichuan/javascript-patterns/blob/master/jquery-patterns/context-and-find.html

According to http://api.jquery.com/find/, jquery implements selector context with the .find function. So either of the methods are equally valid, and none of them are antipatterns.
The link supplied as documentation (http://paulirish.com/2009/perf/) mentions the same fact, and infact states at 12:18 "there no performance gain over doing that, versus the second one [method]"

Using find over context is purely a matter of readability and the preference of the developer.

For loops question

You say

substitute i++ with i = i + 1 or i += 1 to avoid excessive trickiness

So why not substituting i-- with i = i -1 or i -= 1 in the 2 preferred methods ?

function-declarations and recursive

// named function expression
/* Benefits:
* 1. Provides the debugger with an explicit function name: helps stack inspection.
* 2. Allows recursive functions: getData can call itself.
* Issues:
* 1. there are historic quirks with IE
*/
var getData = function getData () {
};

This is very bad idea. We have already possibility for recursion in previous both examples.

While all functions (absolutly annonimus also) can call itself using arguments.callee.

For Example:

var some = function(a){
if(a == 0 || a == 1)
return 1;

var t = arguments.callee; 
return  t(a-1) + t(a-2);  

}
alert(some(5));

literals-and-constructors/primitive-wrappers.html

The last example on literals-and-constructors/primitive-wrappers.html is commented incorrectly:

// primitive string
var greet = new String("Hello there");
// primitive is converted to an object
// in order to use the split() method
greet.split(' ')[0]; // "Hello"
// attemting to augment a primitive is not an error
greet.smile = true;
// but it doesn't actually work
console.log(typeof greet.smile); // "boolean"

It should be:

// string with wrapper
var greet = new String("Hello there");
// object has split() method
greet.split(' ')[0]; // "Hello"
// augmenting object
greet.smile = true;
console.log(typeof greet.smile); // "boolean"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.