@freeethy
2016-02-23T19:51:52.000000Z
字数 5696
阅读 1228
JavaScript
avoiding globals
second
function Waffle() {
if (!(this instanceof Waffle)) {
return new Waffle();
}
this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true;
// testing invocations
var first = new Waffle(),
second = Waffle();
console.log(first.tastes); // "yummy"
console.log(second.tastes); // "yummy"
console.log(first.wantAnother); // true
console.log(second.wantAnother); // true
third
Array literal
if (typeof Array.isArray === "undefined") {
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
}
Array.isArray([]); // true
// trying to fool the check
// with an array-like object
Array.isArray({
length: 1,
"0": 1,
slice: function () {}
}); // false
JSON
parseJSON
Jquery:
// an input JSON string
var jstr = '{"mykey": "my value"}';
var data = jQuery.parseJSON(jstr);
console.log(data.mykey); // "my value"
The opposite of JSON.parse() method is JSON.stringify(). It takes any object or array
(or a primitive) and serializes it into a JSON string.
var dog = {
name: "Fido",
dob: new Date(),
legs: [1, 2, 3, 4]
};
var jsonstr = JSON.stringify(dog);
// jsonstr is now:
// {"name":"Fido","dob":"2010-04-11T22:36:22.436Z","legs":[1,2,3,4]}
forth
Self-Defining Functions
如果某个方法只第一次执行时执行某动作,之后都执行别的方法,可用下面的方式
var scareMe = function () {
alert("Boo!");
scareMe = function () {
alert("Double boo!");
};
};
// using the self-defining function
scareMe(); // Boo!
scareMe(); // Double boo!
scareMe(); // Double boo!
var scareMe = function () {
alert("Boo!");
scareMe = function () {
alert("Double boo!");
};
};
// 1. adding a new property
scareMe.property = "properly";
// 2. assigning to a different name
var prank = scareMe;
// 3. using as a method
var spooky = {
boo: scareMe
};
// calling with a new name
prank(); // "Boo!"
prank(); // "Boo!"
console.log(prank.property); // "properly"
// calling as a method
spooky.boo(); // "Boo!"
spooky.boo(); // "Boo!"
console.log(spooky.boo.property); // "properly"
// using the self-defined function
scareMe(); // Double boo!
scareMe(); // Double boo!
console.log(scareMe.property); // undefined
Immediate Functions
fifth
Partial Application
curring (柯里化)
// a curried add
// accepts partial list of arguments
function add(x, y) {
if (typeof y === "undefined") { // partial
return function (y) {
return x + y;
};
}
// full application
return x + y;
}
Here is the general-purpose currying function:
function schonfinkelize(fn) {
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function () {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
};
}
When to Use Currying
When you find yourself calling the same function and passing mostly the same parameters, then the function is probably a good candidate for currying. You can create a new
function dynamically by partially applying a set of arguments to your function. The
new function will keep the repeated parameters stored (so you don’t have to pass them
every time) and will use them to pre-fill the full list of arguments that the original
function expects.
In JavaScript the knowledge and proper use of functions is critical. This chapter discussed the background and terminology related to functions. You learned about the
two important features of functions in JavaScript, namely:
1. Functions are first-class objects; they can be passed around as values and augmented with properties and methods.
2. Functions provide local scope, which other curly braces do not. Also something to
keep in mind is that declarations of local variables get hoisted to the top of the local
scope.
The syntax for creating functions includes:
1. Named function expressions
2. Function expressions (the same as the above, but missing a name), also known as
anonymous functions
3. Function declarations, similar to the function syntax in other languages
After covering the background and syntax of functions, you learned about a number
of useful patterns, which can be grouped into the following categories:
This implementation is nondestructive, meaning that if a namespace exists, it won’t be re-created:
var MYAPP = MYAPP || {};
MYAPP.namespace = function (ns_string) {
var parts = ns_string.split('.'),
parent = MYAPP,
i;
// strip redundant leading global
if (parts[0] === "MYAPP") {
parts = parts.slice(1);
}
for (i = 0; i < parts.length; i += 1) {
// create a property if it doesn't exist
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
};
This implementation enables all of these uses:
// assign returned value to a local var
var module2 = MYAPP.namespace('MYAPP.modules.module2');
module2 === MYAPP.modules.module2; // true
// skip initial `MYAPP`
MYAPP.namespace('modules.module51');
// long namespace
MYAPP.namespace('once.upon.a.time.there.was.this.long.nested.property');