// the artifial module "jquery" exports the global var "jQuery" externals: { jquery: "jQuery" }
// inside any module var $ = require("jquery");
Example with library included in bundle:
1 2 3 4 5 6 7 8
copy `jquery-git2.min.js` to your local filesystem
// make "jquery" resolve to your local copy of the library // i. e. through the resolve.alias option resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }
// inside any module var $ = require("jquery");
The ProvidePlugin can map modules to (free) variables. So you could define: “Every time I use the (free) variable xyz inside a module you (webpack) should set xyz to require("abc").”
Example without ProvidePlugin:
1 2 3
// You need to require underscore before you can use it var _ = require("underscore"); _.size(...);
Example with ProvidePlugin:
1 2 3 4 5 6 7 8
plugins: [ new webpack.ProvidePlugin({ "_": "underscore" }) ]
// If you use "_", underscore is automatically required _.size(...)
Summary:
Library from CDN: Use <script> tag and externals option Library from filesystem: Include the library in the bundle. (Maybe modify resolve options to find the library) externals: Make global vars available as module ProvidePlugin: Make modules available as free variables inside modules
function authorize(user, action) { if (!user.hasPrivilege(action)) { throw new Error( // 传统写法为 // 'User ' // + user.name // + ' is not authorized to do ' // + action // + '.' `User ${user.name} is not authorized to do ${action}.`); } } 大括号内部可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。
第一个参数:[‘Hello ‘, ‘ world ‘, ‘’] 第二个参数: 15 第三个参数:50 也就是说,tag函数实际上以下面的形式调用。
tag([‘Hello ‘, ‘ world ‘, ‘’], 15, 50) 我们可以按照需要编写tag函数的代码。下面是tag函数的一种写法,以及运行结果。
var a = 5; var b = 10;
function tag(s, v1, v2) { console.log(s[0]); console.log(s[1]); console.log(s[2]); console.log(v1); console.log(v2);
return “OK”; }
tagHello ${ a + b } world ${ a * b}; // “Hello “ // “ world “ // “” // 15 // 50 // “OK” 下面是一个更复杂的例子。
var total = 30; var msg = passthruThe total is ${total} (${total*1.05} with tax);
function passthru(literals) { var result = ‘’; var i = 0;
while (i < literals.length) { result += literals[i++]; if (i < arguments.length) { result += arguments[i]; } }
return result; }
msg // “The total is 30 (31.5 with tax)” 上面这个例子展示了,如何将各个参数按照原来的位置拼合回去。
passthru函数采用rest参数的写法如下。
function passthru(literals, …values) { var output = “”; for (var index = 0; index < values.length; index++) { output += literals[index] + values[index]; }
var message = SaferHTML<p>${sender} has sent you a message.</p>;
function SaferHTML(templateData) { var s = templateData[0]; for (var i = 1; i < arguments.length; i++) { var arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// Don't escape special characters in the template.
s += templateData[i];
i18nWelcome to ${siteName}, you are visitor number ${visitorNumber}! // “欢迎访问xxx,您是第xxxx位访问者!” 模板字符串本身并不能取代Mustache之类的模板库,因为没有条件判断和循环处理功能,但是通过标签函数,你可以自己添加这些功能。
// 下面的hashTemplate函数 // 是一个自定义的模板处理函数 var libraryHtml = hashTemplate <ul> #for book in ${myBooks} <li><i>#{book.title}</i> by #{book.author}</li> #end </ul>; 除此之外,你甚至可以使用标签模板,在JavaScript语言之中嵌入其他语言。
var a = {n:1}; var b = a; // 持有a,以回查 a.x = a = {n:2}; alert(a.x);// --> undefined alert(b.x);// --> {n:2}
我的思路出发点
1.运算符优先级来考虑,.运算优先于=赋值运算 2.右结合性
1 2 3 4 5 6 7 8 9 10 11
var a = {n:1}; /*定义a,赋值为{n:1},假设指向存储地址为add_1*/ var b = a; /*定义b,赋值为a,指向同一存储地址add_1*/ a.x = a = {n:2}; /*(1):定义a.x,赋值为a,即{n:1},存储地址add_1上面的内容被更改 (2):a.x重新赋值为{n:2},存储地址add_1上面的内容被更改 (3):a重新赋值为{n:2},更改存储地址add_2*/ alert(a.x); /*现在a的存储地址add_2,内容为{n:2},上面并不存在a.x属性,所以为undefined*/ alert(b.x); /*现在b的存储地址add_1,内容为{n:1,x:{n:2}},所以b.x为{n:2}*/
let [a, [b], d] = [1, [2, 3], 4]; a // 1 b // 2 d // 4
上面两个例子,都属于不完全解构,但是可以成功。
如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。
1 2 3 4 5 6 7 8 9 10 11
// 报错 let [foo] = 1; let [foo] = false; let [foo] = NaN; let [foo] = undefined; let [foo] = null; let [foo] = {}; ```` 上面的表达式都会报错,因为等号右边的值,要么转为对象以后不具备Iterator接口(前五个表达式),要么本身就不具备Iterator接口(最后一个表达式)。
var { loc: { start: { line }} } = node; line // 1 loc // error: loc is undefined start // error: start is undefined 上面代码中,只有line是变量,loc和start都是模式,不会被赋值。
1
下面是嵌套赋值的例子。
let obj = {}; let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
obj // {prop:123} arr // [true]
1
对象的解构也可以指定默认值。
var {x = 3} = {}; x // 3
var {x, y = 5} = {x: 1}; x // 1 y // 5
var {x:y = 3} = {}; y // 3
var {x:y = 3} = {x: 5}; y // 5
var { message: msg = ‘Something went wrong’ } = {}; msg // “Something went wrong”
1
>默认值生效的条件是,对象的属性值严格等于undefined。
var {x = 3} = {x: undefined}; x // 3
var {x = 3} = {x: null}; x // null 上面代码中,如果x属性等于null,就不严格相等于undefined,导致默认值不会生效。
1
如果解构失败,变量的值等于undefined。
var {foo} = {bar: ‘baz’}; foo // undefined
1
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
// 报错 var {foo: {bar}} = {baz: ‘baz’}; 上面代码中,等号左边对象的foo属性,对应一个子对象。该子对象的bar属性,解构时会报错。原因很简单,因为foo这时等于undefined,再取子属性就会报错,请看下面的代码。
var _tmp = {baz: ‘baz’}; _tmp.foo.bar // 报错 如果要将一个已经声明的变量用于解构赋值,必须非常小心。