Hidden Features of JavaScript? [closed]

2018-12-31 08:54发布

What "Hidden Features" of JavaScript do you think every programmer should know?

After having seen the excellent quality of the answers to the following questions I thought it was time to ask it for JavaScript.

Even though JavaScript is arguably the most important Client Side language right now (just ask Google) it's surprising how little most web developers appreciate how powerful it really is.

30条回答
听够珍惜
2楼-- · 2018-12-31 09:40

with.

It's rarely used, and frankly, rarely useful... But, in limited circumstances, it does have its uses.

For instance: object literals are quite handy for quickly setting up properties on a new object. But what if you need to change half of the properties on an existing object?

var user = 
{
   fname: 'Rocket', 
   mname: 'Aloysus',
   lname: 'Squirrel', 
   city: 'Fresno', 
   state: 'California'
};

// ...

with (user)
{
   mname = 'J';
   city = 'Frostbite Falls';
   state = 'Minnesota';
}

Alan Storm points out that this can be somewhat dangerous: if the object used as context doesn't have one of the properties being assigned to, it will be resolved in the outer scope, possibly creating or overwriting a global variable. This is especially dangerous if you're used to writing code to work with objects where properties with default or empty values are left undefined:

var user = 
{
   fname: "John",
// mname definition skipped - no middle name
   lname: "Doe"
};

with (user)
{
   mname = "Q"; // creates / modifies global variable "mname"
}

Therefore, it is probably a good idea to avoid the use of the with statement for such assignment.

See also: Are there legitimate uses for JavaScript’s “with” statement?

查看更多
深知你不懂我心
3楼-- · 2018-12-31 09:40

You can use objects instead of switches most of the time.

function getInnerText(o){
    return o === null? null : {
        string: o,
        array: o.map(getInnerText).join(""),
        object:getInnerText(o["childNodes"])
    }[typeis(o)];
}

Update: if you're concerned about the cases evaluating in advance being inefficient (why are you worried about efficiency this early on in the design of the program??) then you can do something like this:

function getInnerText(o){
    return o === null? null : {
        string: function() { return o;},
        array: function() { return o.map(getInnerText).join(""); },
        object: function () { return getInnerText(o["childNodes"]; ) }
    }[typeis(o)]();
}

This is more onerous to type (or read) than either a switch or an object, but it preserves the benefits of using an object instead of a switch, detailed in the comments section below. This style also makes it more straightforward to spin this out into a proper "class" once it grows up enough.

update2: with proposed syntax extensions for ES.next, this becomes

let getInnerText = o -> ({
    string: o -> o,
    array: o -> o.map(getInnerText).join(""),
    object: o -> getInnerText(o["childNodes"])
}[ typeis o ] || (->null) )(o);
查看更多
余生请多指教
4楼-- · 2018-12-31 09:41

JavaScript does not have block scope (but it has closure so let's call it even?).

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2
查看更多
旧人旧事旧时光
5楼-- · 2018-12-31 09:41

Maybe a little obvious to some...

Install Firebug and use console.log("hello"). So much better than using random alert();'s which I remember doing a lot a few years ago.

查看更多
心情的温度
6楼-- · 2018-12-31 09:42

To properly remove a property from an object, you should delete the property instead of just setting it to undefined:

var obj = { prop1: 42, prop2: 43 };

obj.prop2 = undefined;

for (var key in obj) {
    ...

The property prop2 will still be part of the iteration. If you want to completely get rid of prop2, you should instead do:

delete obj.prop2;

The property prop2 will no longer will make an appearance when you're iterating through the properties.

查看更多
不再属于我。
7楼-- · 2018-12-31 09:42

Assigning default values to variables

You can use the logical or operator || in an assignment expression to provide a default value:

var a = b || c;

The a variable will get the value of c only if b is falsy (if is null, false, undefined, 0, empty string, or NaN), otherwise a will get the value of b.

This is often useful in functions, when you want to give a default value to an argument in case isn't supplied:

function example(arg1) {
  arg1 || (arg1 = 'default value');
}

Example IE fallback in event handlers:

function onClick(e) {
    e || (e = window.event);
}

The following language features have been with us for a long time, all JavaScript implementations support them, but they weren't part of the specification until ECMAScript 5th Edition:

The debugger statement

Described in: § 12.15 The debugger statement

This statement allows you to put breakpoints programmatically in your code just by:

// ...
debugger;
// ...

If a debugger is present or active, it will cause it to break immediately, right on that line.

Otherwise, if the debugger is not present or active this statement has no observable effect.

Multiline String literals

Described in: § 7.8.4 String Literals

var str = "This is a \
really, really \
long line!";

You have to be careful because the character next to the \ must be a line terminator, if you have a space after the \ for example, the code will look exactly the same, but it will raise a SyntaxError.

查看更多
登录 后发表回答