loveky / Blog

记录点滴
8 stars 2 forks source link

《JavaScript权威指南 第六版》读书会 笔记 #7

Open loveky opened 7 years ago

hanyuxinting commented 7 years ago

var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); trees[3] = undefined;

hanyuxinting commented 7 years ago

3 in trees;

kumamio commented 7 years ago

一、摘要:

1分类:

2.赋值运算符 a op = b op表示 一个运算符。

3. +既是算术运算符,又是字符串运算符。是从左到右工作的。

4对象创建运算符new new constructor (argument) new 首先创建一个新对象,该对象的属性都未被定义。接下来,它将调用特定的构造函数,传递指定的参数,此外,还要把新创建的对象传递给关键字this。这样构造函数就可以使用关键字this来初始化新对象。

5.delete运算符 delete将删除运算数所指定的对象的属性、数组元素或变量。如果删除成功,则返回true. 如果该运算数不能被删除。它将返回false. 但是并非所有的属性和变量都能被删除。某些内部的核心属性和客户端属性不能被删除。var语句声明的用户定义变量也不能删除。

6.函数调用运算符 能过()调用函数。

二、问题

1. 位运算符的应用场景。 2. 逗号运算符: a=0,b=1,c=2; 等价于a=0;b=1;c=2;它的值为2. 3.[]和.都是运算符。 [ ]用于存取数组元素,还可以用于存取对象的属性。 .左边的运算数是一个对象,右边是一个标识符(属性名称)。右边的运算数既不能是字符串,也不能是变量,而应该是属性或者方法的直接量名,而且不需要指明类型。 frames[0].legth document.write("hello")

Onlyfor3ver commented 7 years ago

Q1、 JS中都是表达式吗? Q2、点和方括号两种方式只要上面的区别吗? Q3、 image

Get1、原始表达式包含常量或直接量、关键字和变量。
Get2、 image

Get3、大多数的运算符是标点运算符,少部分是关键字运算符 Get4、避免运算符导致的副作用。

hanyuxinting commented 7 years ago

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators

fannyCai commented 7 years ago

void运算符应用场景?

maplehongye commented 7 years ago

1

控制台结果:

2

3

4

5

get:

1、q = a ? b : c ? d : e ? f : g ; (三目运算符的R结合性) 2、除数为0的结果是正无穷或负无穷,0/0的结果为NaN 3、6.5 % 2.1结果为0.2 4、+运算符优先考虑字符串,但要注意加法结合性对运算顺序的影响(如三个数相加) 5、++运算符后的分号最好手动补全

loveky commented 7 years ago

Get

1. 2. 3.

问题:

1. 2.

  1. 页数
    var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
    trees[3] = undefined;
hanyuxinting commented 7 years ago

Get

JS权威指南读书笔记第四章

Attention

'1' == true
true
'2' == true
false
Onlyfor3ver commented 7 years ago

Get: 1、对象转换成为原始值之后,如果两个操作数都是字符串,那么将依照字母表的顺序对两个字符串进行比较,这里提到的‘字母表顺序’是指组成这个字符串的16位Unicode字符的索引顺序。 2、所有大写的ASCII字母都‘小于’小写的ASCII字母。 3、in运算符希望它的操作数是一个字符串或可以转换为字符串的。 4、为了计算 o instaceof f js首先计算 f.prototype 然后在原型链中查找o 如果找到,那么o是f(或者f的父类)的一个实例。 5、&&并不总返回布尔值。

var b = 2&&4
//b  4

6、&&如果左假,依赖左,如果左真 依赖右。 7、|| 左真返回左,否则返回右。 8、es3规定不允许对eval赋予别名,实际并非如此,当通过别名调用时,eval会将其字符串当成顶层的全局代码来执行。但这不影响主调函数里面的变量。 9、常规eval可以修改局部变量,非常规则修改全局变量。 10、ie9之前没有全局eval()。 11、在严格模式下,eval可以查询或 更改局部变量,但不能在局部作用域中重新定义变量或者函数。

kumamio commented 7 years ago

Get:

1:page74 对象和其本身是相等的,但和其他任何对象都不相等。相应位置相同中的数组元素是相等的两个数组也是不相等的。 image

2:page74 如果其中一个值是NAN,或者两个值都是NAN,则它们不相等。NAN和其它任何值都是不相等的,包括它本身。通过x!==x来判断x是否为NAN,只有在x为NAN的时候,这个表达 式的值 才经true.

3.page79逻辑表达式 &&和||不光是从简单的布尔运算,其实是对真值 和假值的布尔操作和运算。可以有条件的执行两侧的表达式。

Questions:

1:page64 调用表达式: 如果这个表达式是一个属性访问表达式,那么这个调用称作“方法调用”。在方法调用中,执行函数体的时候,作为属性访问主题的对象和数组 便 是其调用方法内部this的指向。这种特性使得在OO的范例中,函数(方法)可以调用其宿主对象。 并不是说,所有方法调用的调用表达式都使用全局对象作为this关键字的值,然而在ES5中,通过严格模式定义的函数,在调用时使用undefined作为this的值 ,this不会指向全局对象。

2:page64 对象创建表达式: js首先创建一个新的空对象,然后通过传入指定的参数并将这个新对象当做this的值 来调用一个指定的函数。这个函数可以使用this来初始化这个新创建对象的属性。

3.page81 赋值表达式(a=b)==0

4.page83 eval()

fannyCai commented 7 years ago

Get:

1、任何数和NaN比较都是返回false 2、&& 并不总是返回true或false 3、数字和字符串 比较运算 比较运算符更偏爱数字,只有在两个操作数是字符串的时候才进行字符串比较

Questions:

1、in运算符? page78 image

2、typeof 返回值,任意宿主对象? page87

maplehongye commented 7 years ago

Get: 1、逻辑表达式 “短路” p80 2、比较运算符与加号运算符,关于数字和字符串的优先级不同 p77

Questions: 1、多次提到表达式具有副作用(赋值,递增,递减,函数调用)p80,这个副作用要怎么去深入理解? 2、赋值表达式副作用 p81,p83 3、delete运算符副作用 p88 4、void运算符副作用 p89 5、逗号运算符副作用 p90

kumamio commented 7 years ago

GET:

  1. page93 空循环体的语句有时是很有用的。 for(i=0;i<a.length;a{i++}=0);

  2. page95 函数定义通常出现在js代码的最顶层,也可以在其它函数体内不能出现在if,while,或者其它任何语句内。

  3. page99 .swtch语句中的匹配是按照===来进行比较的。break和return都可以用于终止swtch语句。

  4. page108 break无法越过函数的边界。无论它带不带标签 。continue只能在循环体中使用。

  5. page110 抛出异常的时候,通常采用Error类型和其子类型。一个Error对象有一个name属性表示错误类型,一个message用来 存放传递给构造函数的字符串。

Q:

  1. page95 函数声明与函数定义的差别: var a=function(){}; function a(){}

  2. page112 break,return,continue可以使得解释器跳出代码块时,解释器在执行新的目标代码之前先执行finally中的语句块。

fannyCai commented 7 years ago

GET: 1、switch case 按照"==="进行比较 2、break的作用是立即退出最内层循环或swicth语句 page 107 3、continue 只能在循环体内使用,其他地方使用报语法错误 page 108 4、return 只能在函数体内执行,当执行到return 语句的时候,函数终止执行,可以单独使用而不必带有表达式,返回undefined page109

Q: empty,label语句?pag117

Onlyfor3ver commented 7 years ago

Get 1、定义函数时,与if while不同,函数体必须用花括号 2、函数定义不能出现在if、while语句或其他任何语句中。。。所以,function并不是真正的语句 3、case做的是 === 比较 4、default可以放在switch的任何地方 5、for in 循环只能遍历可枚举的属性 Q: 1、空语句啥时候使用 P93

loveky commented 7 years ago
for (var i = 0; i < 10; i++) {
    try {
        if (i==5) {
            break;
        }
    }
    finally {
        console.log('Hi')
    }
}
maplehongye commented 7 years ago

GET: 1、当创建一个具有空循环体的循环时,空语句有时是很有用的。 p93 2、变量声明和函数声明会被提前到脚本或嵌套函数的顶部 p94&p95 3、switch语句里的case后面表达式的值是按===进行比较的 p99 4、break和return都可以用来终止switch语句 p100 5、for循环括号里的三个表达式的值都可以省略,但是分号不能省略 p104

Onlyfor3ver commented 7 years ago

Get 1、除了名字和值之外,每个属性还有一些与之相关的值,称为属性特征:1.可写 2.可枚举 3.可配置 2、对象直接量是一个表达式,这个表达式在每次运算都创建并初始化一个新对象。 3、所有通过对象直接量创建的对象都具有同一个原型对象。 4、Objcet.prototype是为数不多的没有原型的对象 5、可以通过传入null给Object.create()来创建一个没有原型的新对象,Object.create()接受第二个参数,这个参数为属性 6、传入Object.prototype来创建一个普通对象 7、点运算符后直接使用保留字在ie8下面报错 8、

var a = {x:'1'}
a.x
"1"
var b = Object.create(a)
b.x
"1"
b.x = 2
2
b.x
2
a.x
"1"   //不会去修改 原型链

9、三种场景给对象设置属性会失败:1.o中的属性p是只读的 2. o中的属性p是继承属性 且他是只读的 3. o中不存在自有属性(即o中没有setter方法) 10、delete不能删除那些可配置性为false的属性 比如通过变量声明和函数声明创建的全局对象属性 11、hasOwnProperty 方法来检测给定的名字是否是对象的自有属性 对于继承属性返回false 12、propertyIsEnumerable 用来检测是自有属性且是可枚举的属性 13、in可以 区分不存在 和 存在但是值为undefined的属性 14、由getter和setter定义的属性称作存取器属性。

Q1.

var a = {}
var a = new Object
var a = new Object()//三者区别
fannyCai commented 7 years ago

GET 1、对象直接变量中的最后一个属性后的逗号,在ie下会报错 2、对象中 [],.的区别 3、避免查询属性报错:var len = book && book.subtitle && book.subitle.length; 4、内置构造函数的原型是只读的,严格模式下任何失败的属性设置会抛出类型错误异常 5、检测属性,in运算符,hasOwnProperty(),propertyIsEnumberable()

Q image

hanyuxinting commented 7 years ago

移步这里

kumamio commented 7 years ago

图片比较多,发在这里

maplehongye commented 7 years ago

GET 1、使用 . 和 [] 获取对象属性的区别 p123 2、对象在查询属性时可以查询到继承属性,但给自身属性赋值时无法修改同名的继承属性 p126 3、查询不存在的属性不会报错,它的值是undefined;但查询一个不存在的对象的属性时会报错,建议使用&&运算符的短路操作获取对象属性 p126 4、delete只能删除自有属性,不能删除继承属性 p127 5、使用in运算符、hasOwnProperty、propertyIsEnumberable检测属性

Q 1、p127 实际开发中怎么避免这种相互引用导致的内存泄漏 var a = {p:{x:1}}; var b = a.p; delete a.p;

fannyCai commented 7 years ago

GET: 序列化对象: JSON 语法支持数字,字符串,布尔值,null NaN,正无穷,父无穷 序列化结果null 日期对象序列化的结果是ISO格式的字符串,但JSON.parse()依然保留它们字符串形态,并不会将其还原为日期对象 undefined,函数,正则,Error对象不能序列化和还原

Q: 什么叫本地化字符串?P142

fannyCai commented 7 years ago

GET 1、通过Array() 构建数组的,数组的索引值没有定义 2、当省略数组中的值的数组是稀疏数组,省略掉的值是不存在的 3、Object.defineProperty() 数组length属性变成只读 4、join() 默认逗号分隔 5、sort() 如果数组包含undefined元素,他们会排到数组的尾部 6、concat()、slice()、splice() 的区别 7、filter()

hanyuxinting commented 7 years ago

第六章

Onlyfor3ver commented 7 years ago

Get 1、一个属性包含了一个名字和四个特性。数据属性的4个特性分别是它的值,可写性、可枚举性、可配置性。P134 2、存取器属性不具有值特性和可写性,它们的可写性是由setter方法存在与否决定的。存取器属性的四个特性是,读取、写入、枚举、配置。P135 3、Object.getOwnPropertyDescriptor只能得到自有属性的描述符。要想得到继承的属性的特性,需要getPrototypeOf()去遍历原型链。 4、Object.definePeoperty传入要修改的对象 要创建或修改的属性的名称以及属性描述符对象 来设置属性的特性。 5、Object.defineProperties来同时修改或创建多个属性。第一个参数是对象,第二个参数是映射表。 6、 如果对象是不可扩展的,则可以编辑已有的自有属性,但不能给它添加新属性 如果属性是不可配置的,则不能修改它的可配置性和可枚举性 如果存取器属性是不可配置的,则不能修改其getter和setter方法,也不能将她转换为数据属性 如果属性是不可配置的,则不能将它转换为存取器属性 如果数据属性是不可配置的,则不能将它的可写性从false修改为true,但可以从true修改为fasle
如果数据属性是不可配置且不可写的,则不能修改它的值。然而可配置但不能写属性的值是可以修改(实际上是先将它标记为可写的,然后修改它的值,最后转换为不可写) 7、isPrototypeOf 用来检测一个对象是否是另外一个对象的原型,跟instanceof类似,但是instanceof 的右操作符通常是一个类 8、对象的类属性是一个字符串,用以表示对象的类型信息。Null Number String Boolean Object Array Regexp 9、一旦将对象转换为不可扩展的,就无法再将其转换为可扩展的了。Object.esExtensible()来判断是否可扩展 Object.preventextensions()可以将对象转换为不可扩展的。Object.seal()能够将对象设置为不可扩展的,还可以将所有自有属性都设置为不可配置的。使用了seal就不能解seal了。使用Object.isSealed()来检测是否封闭了。 10、Object.freeze()将更严格地锁定对象,除了拥有seal的功能外,还可以将所有数据属性设置为只读。Object.isFrozen来检测是否冻结。 11、JSON.stringify()只能序列化对象可枚举的自有属性。不能序列化的属性,在输出的字符串中省略掉 12、toLocaleString()方法返回一个表示这个对象的本地化字符串。其实只有数字、日期和时间做本地化的转换

Onlyfor3ver commented 7 years ago

1、最大索引,2的32次幂减2 2、用数字索引来访问数组元素一般来说比访问常规的对象属性要快得多。???? 3、可以使用负数或非负整数来索引数组。非负整数,数组索引,而非对象属性。不是非负,常规的对象属性,而非数组索引。P146页。 4、稀疏数组 是包含从0开始的不连续索引的数组,不连续意味着元素不存在,跟直接量里面创建数组时省略不同。使用 in 可以检测区别。有返回true,无返回false。数组直接量是不会创建稀疏数组 5、数组可以通过设置length的方法,删除数组中的元素。 6、数组中的delete,是将数组变成稀疏的。要想不变稀疏 使用slice() push 最后植入 pop 最后删除 unshift首部植入 shift首部删除 7、Array.join()方法将数组中所有的元素都转化为字符串连接在一起。返回字符串。默认逗号连接。相对应的逆向方法是String.split() 8、Array.reverse()数组反转。旧数组 Array.sort()将元素排序,undefined元素排到数组尾部,也可以给sort传入一个比较函数。旧数组 concat()返回新数组 slice()返回指定数组的一个片段或子数组。两个参数分别为片段的开始和结束(返回结果不包含第二个参数位置的元素)。只有一个参数,就是从指定位置到结尾。-1指最后一个元素。返回新数组。 splice()是在数组内插入或删除,不会产生稀疏数组。旧数组操作。第一个参数制定了插入或删除的起始位置,第二个参数指定了应该从数组中删除的元素的个数。如果第二个参数没有,则从开始到结尾的所有元素都会被删除。splice中,第三个开始的参数制定了插入的内容。 forEach 三个参数 分别是 值,索引,数组 通常只用第一个。使用forEach想提前终止,需要放在try中。 map方法将每个元素传递给制定函数,返回结果新数组。 filter方法传递的函数是用来逻辑判定的,该函数返回true false 。filter返回的数组总是稠密的。 every全部满足,返回true some有一个满足 返回true reduce reduceRight方法使用指定的函数将数组元素进行组合,生成单个值。reduce 第一个参数是函数,第二个是函数初始值

maplehongye commented 7 years ago

20170317 1、数组有“常规的对象属性”和“数组索引”两种类型的属性,非负整数的字符串可以当做数组索引使用,例如 a[1.000] 与a[1]相等 p146 2、数组没有越界的概念,当试图查询不存在的属性时,会得到undefine值 p146 3、数组直接量中的省略值会创建稀疏数组,书中写错了 p147 clipboard1

4、delete数组的索引属性与delete对象的常规属性,有所区别 delete对象属性 clipboard2

delete数组索引 clipboard3

5、如果数组是稀疏的,使用数组元素的时候应先检测一下,排除null,undefinded,和不存在的元素 p150 数组有null的元素吗?不存在的元素不是都会返回undefined吗?

6、join()不传值,默认是用逗号连接,设置css某些属性的时候可以在数组后多加个undefined元素,然后用join('px ')这种去连接。

7、sort()方法会把数组里的undefined元素排到数组尾部 8、concat()的参数为数组时,连接的是数组的元素,而非数组本身 9、slice()不会修改原数组,splice()会修改,参数为数组时,要避免原数组被修改 10、es5新增的数组方法了解:forEach, map, filter, every, some, reduce, reduceRight,indexOf等

kumamio commented 7 years ago

第6章(对象): GET: 1.page 135 getOwnPropertyDescriptor() ,数据属性,存储器属性。defineProperty , defineProperties 2.对象的三个属性 Q: 1.

第7章(数组): GET: image -1 Q: 1.page161 有关检查对象的类属性的方法的理解。 2.怎样理解这两个过程? var x,y,z; [x,y,z]=[1,2,3] console.log(x); //log 1 console.log(y); //log 2 console.log(z); //log 3 如果是: var s=[x,y,z]; s=[1,2,3] console.log(x);// log undefined

hanyuxinting commented 7 years ago

https://github.com/hanyuxinting/Blog/issues/9

kumamio commented 7 years ago

第八章:函数 Get: 1.函数声明语句不能出现在条件判断语句,或者try/catch/finally以及with语句中。 2.方法链:当方法的返回值 是一个对象,这个对象还可以调用它的方法。 3.凡没有形参的构造函数在调用的时候,可以省略(); 4.可以使用call() 和apply()来间接的调用参数。 5.函数参数传递都是值 传递,不是引用传递。

function addTen(num) { num += 10; return num; } var count = 20; var result = addTen(count); alert(count); //20,没有变化 alert(result); //30 image

function setName(obj) { obj.name = "Nicholas"; } var person = new Object(); setName(person); alert(person.name); //"Nicholas" image

function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); //"Nicholas" image

实参可选,是因为arguments是一个类数组对象。 实参对象有callee和caller属性。callee指向当前正在执行的函数。 6.page171嵌套函数的this不会从调用它的函数中继承this。 image

fannyCai commented 7 years ago

GET

函数声明不能出现在循环,条件判断,try/catch/finally及with语句中 arguments是一个数组对象

Q 1、函数形式调用的函数通常不使用this关键字,不过‘this’ 可以用来判断当前是否是严格模式?p169 2、函数体内的执行顺序?

image

Onlyfor3ver commented 7 years ago

1、indexOf 和 lastIndeOf寻找给定值的元素,找到就返回第一个出现位置的索引,没找到返回-1.该方法可以指定第二个参数,第二个参数指开始值。 2、Array.isArray可以检测是不是数组。 3、一种常常完全合理的看法把拥有一个数值length属性和对应非负整数属性的对象看成一种类型的数组。字符串被当作数组看待时,是只读的,也就是说,不能修改其中的值,也不能使用push sort reverse splice等方法。 4、var a = (function(x) {return xx})(10) var b = (function(x) {return xx})(10) 区别 5、es3 和非严格es5下,调用上下文是指全局对象,在严格模式则是undefined、以函数形式调用的函数通常不使用this关键字。方法调用中的this通常指的是调用该方法的对象。 6、凡是没有形参的构造函数调用都可以省略圆括号。构造函数调用创建一个新的空对象,这个对象继承自构造函数的prototype属性,构造函数试图初始化这个新创建的对象,并将这个对象用做其调用上下文。 7、arguments是指向实参对象的引用,这个实参对象就是一个类数组对象。 8、P175 如果实参对象是一个普通数组的话,第二条console.log(x)的语句绝对不会是null??? 9、严格模式不能使用arguments作为参数名或者局部变量名。 10、实参对象定义了callee和caller属性。严格模式下对这两个属性的读写都会报错,非 严格模式下,callee属性指代当前正在执行的函数。caller指代正在执行函数的函数。caller实现的不是很多。callee很有用,可以在匿名函数中递归调用本身。argument.callee();

maplehongye commented 7 years ago

Get: 1、仅以语句声明形式定义的函数,不能出现在循环,条件判断,try/catch/finally以及with语句中 2、方法调用和函数调用在“调用上下文”上有很大区别,方法调用的上下文为调用方法的对象 3、链式调用的原理 p171 4、javascrip不允许对this赋值,且this没有作用域的限制 5、构造函数的调用与普通函数调用有很大的不同,构造函数的调用会创建一个新的对象,这个对象继承自构造函数的prototype属性。构造函数对这个新对象进行初始化,并将这个新对象作为“调用上下文”。构造函数通常不使用return关键字,它返回的是创建的新对象。如果在构造函数里显式的返回一个对象,那么调用构造函数表达式的值就是return的对象;如果return的不是对象,则忽略return的值,使用构造函数创建的新对象作为返回值 6、省略的实参都是undefined,多出的参数会自动省略 7、arguments并不是真正的数组,它是一个实参对象,只是碰巧具有以数字为索引的属性 8、严格模式下无法使用arguments作为形参名或局部变量名,也不能给arguments赋值 9、函数不仅是语法,也可以是值。 p178 10、函数可以拥有属性 p180

Q 1、方法的链式调用和构造函数的链式调用,有何区别?p171 2、函数赋值给数组元素,实际开发中,有这样的应用吗? var a = [function(x) {return x*x;}, 20]; a[0](a[1]); 400 3、递归函数使用时要注意什么?

maplehongye commented 7 years ago
function f(x) {
    if(x === 1){
        return 1;
    }else{
        return x * f(x-1);
    }
}

f(5);
var obj1 = {
    num: 5,
    f: function(x){
        if(x === 1){
            return 1;
        }else{
            return x * this.f(x-1);
        }
    }
}

obj1.f(5);

递归函数是要告诉我们:函数既是方法可以调用,又可以作为值当参数传递?

fannyCai commented 7 years ago

GET 闭包 :为了能够读取其他函数的内部变量的函数 闭包的用处 1、读取函数内部的变量 2、让这些变量的值始终保持在内存中

Q

var x = "globol value";
var getValue = function(){
    console.info(x); 
    var x = "local value";
    console.info(x); 
}
 getValue();

var x = "globol value";
function getValue(){
    console.info(x); 
    x="local";
    console.info(x); 

}
 getValue();

2、将不使用的局部变量全部删除?

hanyuxinting commented 7 years ago

GET:

闭包:

kumamio commented 7 years ago

8.6闭包: 1.page183 在定义定义函数的作用域外调用这个函数时,f()的作用域链包括局部变量在外部调用依然有效。关联到闭包的作用链都是“活动的”。 image

2.对(function())()的理解 (function()){}相当于: image image image

Onlyfor3ver commented 7 years ago

1、调用闭包时,相当于创建了不同实例,因此互不干扰。 2、当调用函数时闭包所指向的作用域链和定义函数时的作用域链不是同一个作用域链时。P183 image

maplehongye commented 7 years ago

1、查了一些资料,发现大家对闭包的定义好像不是太统一,所以看着有点乱

p182 - p183 函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数的作用域内,这种特性在计算机科学文献中称为闭包.....

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures 闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。

关于词法作用域: 在 JavaScript 中,变量的作用域是由它在源代码中所处位置决定的(显然如此),并且嵌套的函数可以访问到其外层作用域中声明的变量。

2、一些和闭包有关的例子

var scope = 'global scope';

// 闭包
function fun1(){
    var scope = 'local scope';
    function f(){
        return scope;
    };

    // 返回函数调用表达式
    return f();
}
// 闭包
function fun2(){
    var scope = 'local scope';
    function f(){
        return scope;
    };

    // 返回函数名
    return f;
}

// 非闭包函数
function fun3(){
    var scope = 'local scope';
    function f(){
        return scope;
    };

    // 直接执行函数调用
    f();
}

image

2、一个函数中可以定义多个闭包,引申:在函数中循环创建闭包的注意事项

p185 counter()函数 p187 countfuns()函数 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures image

Q:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures 在循环中创建闭包:一个常见错误 性能考量对应的例子

maplehongye commented 7 years ago

实现在循环中创建闭包

http://jsbin.com/meculesiwa/edit?js,console,output

maplehongye commented 7 years ago

实现在循环中创建闭包2

fun3中for循环内部是不建议定义function的,这里只是演示效果

function fun3(){
  var a = 'local-3',
      f3=[];

  for(var i = 0; i< 10; i++){
    f3[i] = function(){
      return i;
    }
  };

  return f3;
}

image

function fun4(){
  var a = 'local-4',
      f4=[];

  for(var i=0; i < 10; i++){
    f4[i] = f(i);
  }

  return f4;

  function f(x){
     return x;
  }
}

image

function fun5(){
  var a = 'local-5',
      f5=[];

  for(var i=0; i < 10; i++){
    f5[i] = f(i);
  }

  return f5;

  function f(x){
     return function(){
       return x;
     };
  }
}

image

fannyCai commented 7 years ago

GET call,apply 动态改变this,当一个object没有某个方法,单其他的有,可以借助call或apply用其他队形方法操作

function fruits() {}

fruits.prototype = {
    color: "red",
    say: function() {
        console.log("My color is " + this.color);
    }
}

var apple = new fruits;
apple.say(); 

banana = {
    color: "yellow"
}
apple.say.call(banana);
apple.say.apply(banana)

二者区别

func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])

了解常用用法

1、数组追加

var array1 = [1,2,3]; 
var array2 = [4,5,6]; 
Array.prototype.push.apply(array1, array2); 

2、获取数组中的最大值和最小值

var  numbers = [5, 458 , 120 , -215 ]; 
var maxInNumbers = Math.max.apply(numbers, numbers)

3、精确判断对象类型 Object.prototype.toString.call(obj)

bind,call,apply 区别

bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用

var obj = {
    x: 81,
};

var foo = {
    getX: function() {
        return this.x;
    }
}
foo.getX.call(this,obj)
foo.getX.apply(obj)
foo.getX.bind(obj)() 

Q

var  numbers = [5, 458 , 120 , -215 ]; 
var maxInNumbers = Math.max.apply(Math, numbers)
hanyuxinting commented 7 years ago

Get

1. bind 方法,函数绑定在对象上,但并不影响对象,对象还是之前的对象。该方法会返回一个新函数,新函数会把函数当做对象的函数执行。

function f(y){
    return this.x + y;
}

var o = {x:1};
var g = f.bind(o);
g(2); //3
function f(y){
    return this.x + y;
}

var o = {x:1}; 
f(3) //NaN

o.f // undefined
o //没有变化

理解闭包。

Function.prototype.bind = function(o){
    var self = this;
    var boundArgs = arguments;

    console.log(arguments.length) //2

    return function(){
        var args = [], i;
        for(i =1; i<boundArgs.length; i++){
            args.push(boundArgs[i]);
        }

        console.log(arguments == boundArgs)//false

        console.log(arguments.length)//1

        for(i=0;i<arguments.length; i++){
            args.push(arguments[i]);
        }

        return self.apply(o, args);
    }
}

var sum = function(x, y){
    return x+y;
}
var succ = sum.bind(null, 1);

succ(3);//4

2. toString()

succ.toString()

/*
"function (){
        var args = [], i;
        for(i =1; i<boundArgs.length; i++){
            args.push(boundArgs[i]);
        }

        console.log(arguments == boundArgs)

        console.log(arguments.length)

        for(i=0;i<arguments.length; i++){
            args.push(arguments[i]);
        }

        return self.apply(o, args);
    }"

*/

3. Function 构造函数-很少用呀!!!

Function('x','y')
结果:
function anonymous(x
/*``*/) {
y
}
var scope = 'global';
function testFunction(){
    var scope = 'local';
    return new Function('return scope');
}

testFunction()(); // global

4. 可调用的对象-一个非函数的可以被调用的对象。。Question..

function isFunction(x){
    return Object.prototype.toString.call(x) === '[object Function]'
}

5. 函数式编程-操作函数

map() 方法创建一个新数组,其结果是该数组中的每个元素调用一个提供的函数。 reduce() 方法对累加器和数组的每个值 (从左到右)应用一个函数,以将其减少为单个值。 every() 方法测试数组的所有元素是否都通过了指定函数的测试。

var sum = function(x, y){
    return x+y;
}

var square = function(x){
    return x*x;
}

var data = [1,1,2,3,4,5,6];
var mean = data.reduce(sum);
console.log(mean);
mean = mean/data.length;
console.log(mean);

var deviations = data.map(function(x){
    return x-mean;
});

var stddev = Math.sqrt(deviations.map(square).reduce(sum)/(data.length-1));
Onlyfor3ver commented 7 years ago

1、bind方法是将函数绑定至某个对象。f.bind(o);

function f(y) {return this.x + y}
undefined
var x = 2 
undefined
f(2)
4
var o = {x:1}
undefined
var g = f.bind(o)
undefined
g(2)
3

2、toString() 内置函数返回 [native code] 3、function构造函数允许js在运行时动态地创建并编译函数,全局作用域

var scope = 'global'
undefined
function constructFunction() {var scope = 'local' ; return new Function('return scope')}
undefined
constructFunction()
function anonymous() {
return scope
}
constructFunction()()
"global"

4、call和apply看做是某个对象的方法,通过调用方法的形式来间接调用函数。他们的第一个实参是要调用函数的母对象。

var array1 = [1,2,3]; 
var array2 = [4,5,6]; 
Array.prototype.push.apply(array1, array2);
kumamio commented 7 years ago

GET: 函数可以通过构造函数Funtion来定义。

1.问题:Function的call,apply方法在哪里?

image

2.对bind方法的理解

image

3.检查一个对象是否是真正的函数对象,哪种方法好 image

maplehongye commented 7 years ago

Q: 1、p191:柯里化,es5的bind会把第一个实参后面的参数传入this 2、p192:es5的bind方法怎么实现构造函数

fannyCai commented 7 years ago

GET 特殊字符

\
^
$
* {0,}
+{1,}
?{0,1}
(x) 
(?:x)    ??
x(?=y)
x(?!y) 
\d
\D
\w
\W
\s
\S

/\d+(?!\.)/.exec("3.141")

常使用的方法 Regexp.extc() 1、返回数组 2、区别于string.match 可以使用g标志 Regexp.test() 返回true或false

String.match() 1、找到一个或多个正则表达式匹配的结果,没有返回null 2、regexp 没有“g” 值执行一次匹配 3、regexp 有“g” 全局匹配 4、不提供()这种写法,也不会记录每个匹配子串在string中的位置 image

String.search()

1、返回第一匹配regexp子串的开始位置,没有找到返回-1 2、不执行g标志

String.replace() 1、替换给定的正则匹配的子串 2、在replace中$有特殊含义

$1-$99 匹配第1-99个正则中的()内容 $& 匹配正则的子串 $` 匹配子串的左边 $' 匹配子串的右边 $$ 美元符号


var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");

var str2 = '"1"string"2","3"'
var reg = /"([^"]*)"/g
str2.replace(reg,"''$1''")

Q (?:x)

Onlyfor3ver commented 7 years ago

1、正则表达式直接量/reg/ 2、标点符号前加反斜线(防止记不清楚哪些需要加反斜线)。数字字母不要用反斜线转译(有些字母加反斜线有特殊意义) 3、将直接量字符单独放进方括号内就组成了字符类。一个字符类可以匹配它所包含的任意字符。

var a = /[a,b,c]/
a.test(a)   //true
a.test('d') //false
a.test('a') //true
var a = /[^a,b,c]/
a.test('a') //false

4、"+"用来匹配前一个模式的一个或多个副本。 {n,m}匹配前一项至少n次,但不能超过m次。 {n,} 匹配前一项n次或者更多次 {n} 匹配前一项n次 ? 匹配前一项0次或者1次,也就说前一项是可选的。等价于{0,1}

String.match(reg) 返回结果是一个由匹配结果组成的数组。可以设置g。返回所有匹配。如果不执行全局匹配,则返回的数组中,第一个元素时匹配的字符串,余下的元素则是正则表达式中用圆括号括起来的子表达式。 String.split(reg) 12、macth方法的参数是RegExp对象,exec方法是一个字符串。与match不同的是、exec方法无论是否有修饰符g,都会返回同样的匹配完整的信息 13、reg.test(xxx) 14、RegExp(正则主体,修饰符(可选)) 15、P259 对正则表达式中前一个表达式的引用,并不是指对子表达式模式的引用,而指的是与那个模式相匹配的文本的引用???? 写法非法。