第四章 4.1.3 提到访问变量有按值和按引用两种方式,而函数参数只能按值传递。var a = &b; //这是所谓的按引用传递吗?var a=25; function test(num){ num +=10; return num; } var re = test(a); alert(re); //35 alert(a); //25 这是所谓的按值传递吗var a = new Object(); function test(num){ num.name = 'zhang'; } test(a); alert(a.name); //'zhang' 这是所谓的按引用传递吗(但是书上说此例子还是按值传递),为此书中举了下面的例子var a = new Object(); function test(num){ num.name = 'zhang'; num = new Object(); num.name = 'kk'; } test(a); alert(a.name); //'zhang'这里的按引用和按值如何理解?请举例子。
另外,对于你给出的第二个例子,当执行这一句:“num = new Object();“”的时候,num会丢掉原来的引用的地址值,也就会丢失对传入参数所引用实体的CRUD权限了,就像替丢失了原来帐户的密码,记录了一个新密码,那对原来帐户的操作权限自然不复存在,而当函数执行完毕,新建的new Object()会被销毁,那引用的地址值也毫无意义可言
var color = 'blue'; function changeColor(){ if(color === 'blue'){ color = 'red'; } else { color = 'blue'; } } 谢谢你的耐心解答,我仔细琢磨一下,我知道第一个if(color==‘blue’)这个作用域链会在外部环境寻找到color这个变量。紧接着下面一行color='red'; 因为前面没有var 所以被加载到了全局变量中,也就是替换了var color='blue';所以弹出了red。我是这样理解的。
var color = 'blue'; function changeColor(){ if(color === 'blue'){ color = 'red'; } else { color = 'blue'; } } 谢谢你的耐心解答,我仔细琢磨一下,我知道第一个if(color==‘blue’)这个作用域链会在外部环境寻找到color这个变量。紧接着下面一行color='red'; 因为前面没有var 所以被加载到了全局变量中,也就是替换了var color='blue';所以弹出了red。我是这样理解的。既然if(color="blue")已经找到了外部环境的变量,那么color="red"这一句的color为什么不能是外部环境的变量呢?感觉这里楼主理解有误。
var color = 'blue'; function changeColor(){ if(color === 'blue'){ color = 'red'; } else { color = 'blue'; } } 谢谢你的耐心解答,我仔细琢磨一下,我知道第一个if(color==‘blue’)这个作用域链会在外部环境寻找到color这个变量。紧接着下面一行color='red'; 因为前面没有var 所以被加载到了全局变量中,也就是替换了var color='blue';所以弹出了red。我是这样理解的。既然if(color="blue")已经找到了外部环境的变量,那么color="red"这一句的color为什么不能是外部环境的变量呢?感觉这里楼主理解有误。 谢谢你的耐心解答
function test(num){
num +=10;
return num;
}
var re = test(a);
alert(re); //35
alert(a); //25
这是所谓的按值传递吗var a = new Object();
function test(num){
num.name = 'zhang';
}
test(a);
alert(a.name); //'zhang'
这是所谓的按引用传递吗(但是书上说此例子还是按值传递),为此书中举了下面的例子var a = new Object();
function test(num){
num.name = 'zhang';
num = new Object();
num.name = 'kk';
}
test(a);
alert(a.name); //'zhang'这里的按引用和按值如何理解?请举例子。
看到你提这个问题,我又回顾了一下这一小节的内容,简单说一下:
首先看第一句话:
-- ECMAScript 中所有函数的参数都是按值传递的。--
这可以看作一个定理,就看能不能去理解了。
对于第一个例子:向参数传递基本类型的值,我想楼主应该不存在疑惑,就是按值传递。
对于第二个例子:向参数传递对象,对象的话都是同一个引用,也就是说楼主写的对象a和参数的num是同一个引用,书上有一句话是这样说的:
-- 即使这个变量是按值传递的, obj 也会按引用来访问同一个对象。--
所以可以得出结论,向参数传递对象也是按值传递。最后的那个例子就是为了说明这一点,
书中的最后一句话可以帮助理解:
-- 可以把 ECMAScript 函数的参数想象成局部变量。--不知道解释的清楚不清楚,看9楼、10楼的兄弟解释的已经很不错了,建议把书用读出来的方式再理解一遍。
function changeColor(){
if(color === 'blue'){
color = 'red';
}else{
color = 'blue';
}
}
changeColor();
alert(color); //red
最后弹出了red。按照正常思路,js函数里面可以访问外部也就是全局变量。这个red是怎么传出来的。我仔细看了下书,有2个理解,第一理解:声明变量没有var的时候是全局变量 也就是if里面 color='red'; 第二种理解:由于作用域链的关系,会从内到外查找color这个变量,由于最先在内部(也就是函数体内)查到了color这个变量,停止执行。所以弹出了red。不知道我理解的那个对?另个问题是js没有块级作用域,也就是说{}里面的代码执行完毕不会被销毁。
for(var i=0;i<10;i++){
i;
}
alert(i); //10 这个例子 为什么弹出了10 我理解应该依次弹出0-9共10个数字啊,或者弹出9,因为i<10 怎么也不可能弹出10啊
你设个断电逐步跟踪就能直观看到,在for循环代码块执行完后才会执行到后面的语句,也就是alert(i)只会在最后执行一次。由于for循环中当变量i自加到i=10的时候for循环才结束,所以alert(i)的结果是10
function changeColor(){
if(color === 'blue'){
color = 'red';
} else {
color = 'blue';
}
}这里是因为作用域链,但不是找到function内部的color(function内部哪里定义color了?),而是找到了function外部的color,所以改变的就是function外部的color的值,自然就弹出了red。
给楼主两个例子,楼主可以慢慢理解理解作用域链(不要被“作用域链“这个名词困住了思想):<script type="text/javascript">
var color = "blue" ;
function changeColor() {
var color = "blue" ;
if(color == "blue") {
color = "red" ;
} else {
color = "blue" ;
}
}
changeColor() ;
alert(color) ;
</script><script type="text/javascript">
function changeColor() {
color = "blue" ;
if(color == "blue") {
color = "red" ;
} else {
color = "blue" ;
}
}
changeColor() ;
alert(color) ;
</script>
看到你提这个问题,我又回顾了一下这一小节的内容,简单说一下:
首先看第一句话:
-- ECMAScript 中所有函数的参数都是按值传递的。--
这可以看作一个定理,就看能不能去理解了。
对于第一个例子:向参数传递基本类型的值,我想楼主应该不存在疑惑,就是按值传递。
对于第二个例子:向参数传递对象,对象的话都是同一个引用,也就是说楼主写的对象a和参数的num是同一个引用,书上有一句话是这样说的:
-- 即使这个变量是按值传递的, obj 也会按引用来访问同一个对象。--
所以可以得出结论,向参数传递对象也是按值传递。最后的那个例子就是为了说明这一点,
书中的最后一句话可以帮助理解:
-- 可以把 ECMAScript 函数的参数想象成局部变量。--不知道解释的清楚不清楚,看9楼、10楼的兄弟解释的已经很不错了,建议把书用读出来的方式再理解一遍。
赶脚用var a ={} 简洁点,不要用var a = new Object() ,呵呵
你设个断电逐步跟踪就能直观看到,在for循环代码块执行完后才会执行到后面的语句,也就是alert(i)只会在最后执行一次。由于for循环中当变量i自加到i=10的时候for循环才结束,所以alert(i)的结果是10
谢谢,很直观很容易理解。
var color = 'blue';
function changeColor(){
if(color === 'blue'){
color = 'red';
} else {
color = 'blue';
}
}
谢谢你的耐心解答,我仔细琢磨一下,我知道第一个if(color==‘blue’)这个作用域链会在外部环境寻找到color这个变量。紧接着下面一行color='red'; 因为前面没有var 所以被加载到了全局变量中,也就是替换了var color='blue';所以弹出了red。我是这样理解的。
var color = 'blue';
function changeColor(){
if(color === 'blue'){
color = 'red';
} else {
color = 'blue';
}
}
谢谢你的耐心解答,我仔细琢磨一下,我知道第一个if(color==‘blue’)这个作用域链会在外部环境寻找到color这个变量。紧接着下面一行color='red'; 因为前面没有var 所以被加载到了全局变量中,也就是替换了var color='blue';所以弹出了red。我是这样理解的。既然if(color="blue")已经找到了外部环境的变量,那么color="red"这一句的color为什么不能是外部环境的变量呢?感觉这里楼主理解有误。
var output = "";
if(typeof args.name == 'string'){
output += "name:"+args.name + "\n";
}
alert(output);
}
displayInfo({
name: "Greg"
});会弹出 name:Gregif(typeof 5 == 'number'){alert 2;}这是我自己写的,为什么报错SyntaxError: Unexpected number
var color = 'blue';
function changeColor(){
if(color === 'blue'){
color = 'red';
} else {
color = 'blue';
}
}
谢谢你的耐心解答,我仔细琢磨一下,我知道第一个if(color==‘blue’)这个作用域链会在外部环境寻找到color这个变量。紧接着下面一行color='red'; 因为前面没有var 所以被加载到了全局变量中,也就是替换了var color='blue';所以弹出了red。我是这样理解的。既然if(color="blue")已经找到了外部环境的变量,那么color="red"这一句的color为什么不能是外部环境的变量呢?感觉这里楼主理解有误。
谢谢你的耐心解答
楼主仔细看一下这句话,就可以发现错误了。PS:不要这样写代码,即使这么短的语句,最好也分行来写,如果你分行写,可能就不会出这个粗心的错误了。
楼主仔细看一下这句话,就可以发现错误了。PS:不要这样写代码,即使这么短的语句,最好也分行来写,如果你分行写,可能就不会出这个粗心的错误了。
唉 alert()后面没加()啊 嘿嘿
检测数组
value instanceof Array //返回true or false
instantceof问题在于,它假定单一的全局执行环境.为了解决这个问题,可以用Array.isArray(value)
红色部分怎么理解啊。谁能举个例子?5.2.2
转换方法
var colors =['red','blue','green'];
alert(colors);
由于alert()要接收字符串参数,所有它会在后台调用toString()方法。
alert()一定要接收字符串参数吗,那alert({})是什么?
var obj = {
a:1,
toString:function(){return "value"}
};
alert(obj);//返回value
写了几篇笔记了,在我博客http://www.liguangliang.com.cn/?sort=13如果觉得不错,给我点个广告支持吧,谢谢咯
对象原来可以自定义toString函数啊,呵呵
alert会调用toString方法,为何console.info不会?
除了alert哪些函数也会自动调用toString方法呢?
楼主仔细看一下这句话,就可以发现错误了。PS:不要这样写代码,即使这么短的语句,最好也分行来写,如果你分行写,可能就不会出这个粗心的错误了。
唉 alert()后面没加()啊 嘿嘿 脑图太庞大,赶脚乱了
谢谢你的解答。我明白了,书上字面意思表达不正确。alert()可以接受任意类型的值.只是它会调用参数的toString()方法。这个toString方法可以重写.例如:
alert({toString:function(){return 666}});
楼主仔细看一下这句话,就可以发现错误了。PS:不要这样写代码,即使这么短的语句,最好也分行来写,如果你分行写,可能就不会出这个粗心的错误了。
唉 alert()后面没加()啊 嘿嘿 脑图太庞大,赶脚乱了
我也感觉到了,有没有好的建议?
今天看了栈方法,队列方法,重排序方法。更新一下笔记栈方法
栈是一种lifo(last-in-first-out,后进先出)的数据结构,也就是最新添加的项最早被移除.而栈中项的插入和移除,只发生在一个位置--栈的顶部.
push()方法可以接受任意数量的参数,把他们添加到数组末尾。
pop()从数组末尾移除最后一项,减少数组的length值var colors =new Array();
count = colors.push('black');
alert(count); //1var item = colors.pop();
alert(item); //'black'
alert(colors.length); //0列队方法
列队是一种fifo(first-in-first-out,先进先出).队列在列表的末端添加项,从列表的前端移除项.
shift()它能够移除数组第一项并返回该项,同时将数组长度减1.
unshift()从前端添加任意个项并返回新数组长度.重排序方法
reverse()反正数组顺序
sort()会调用数组每个项的toString()方法,安装字母顺序排列.如果是数字,需要传递第二个函数参数
function sortNumber(a,b){
return a - b; //若a小于b,a应该出现b之前.也就是说 -1 a在b前 0 不动 1 a在b后
}
var arr =[10,5,40,25,1000,1];
alert(arr.sort(sortNumber));
今天整理了下5.5章下的5.5.1 5.5.2 5.53
function类型
js函数实际上是对象.每个函数都是function类型的实
例,而且都与其他引用类型一样具有属性和方法.
函数声明1
function sum(num1,num2){
return num1+num2;
}
函数声明2
var sum = function(num1,num2){
return num1 + num2;
}; //不要忘记结束符
函数声明3
var sum = new Function('num1','num2','return
num1 + num2'); //最后一个参数始终是函数体,相当于
{}里面的内容函数是对象,函数名是指针.一个函数可能会有多个名字
function sum(num1,num2){
return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum;
alert(anotherSum(10,10)); //20
sum = null;
alert(anotherSum(10,10)); //20函数没有重载,同命名函数,后面会覆盖前面的函数声明与函数表达式
解析器在向执行环境中加载数据时,会率先读取函数声明在执行任何代码之前可用.而函数表达式,则必须等到解析器执行到它所在代码行,才会真正被解释执行.
alert(sum(10,10)); //20
function sum(num1,num2){
return num1 + num2;
}alert(sum(10,10)); //错误
var sum = function(num1,num2){
return num1 + num2;
};作为值的函数
因为js中的函数名本身就是变量,所以可以作为值来使用.
function a(ag){
return ag+10;
}function b(ag){
return ag;
}alert(b(a(10))); //20function callSomeFunction(someFunction,someArgument){
return someFunction(someArgument);
}function add10(num){
return num + 10;
}
var re = callSomeFuntion(add10,10); //add10不加()不会执行
alert(re); //20
今天整理了下5.5章下的5.5.1 5.5.2 5.53
function类型
js函数实际上是对象.每个函数都是function类型的实
例,而且都与其他引用类型一样具有属性和方法.
函数声明1
function sum(num1,num2){
return num1+num2;
}
函数声明2
var sum = function(num1,num2){
return num1 + num2;
}; //不要忘记结束符
函数声明3
var sum = new Function('num1','num2','return
num1 + num2'); //最后一个参数始终是函数体,相当于
{}里面的内容函数是对象,函数名是指针.一个函数可能会有多个名字
function sum(num1,num2){
return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum;
alert(anotherSum(10,10)); //20
sum = null;
alert(anotherSum(10,10)); //20函数没有重载,同命名函数,后面会覆盖前面的函数声明与函数表达式
解析器在向执行环境中加载数据时,会率先读取函数声明在执行任何代码之前可用.而函数表达式,则必须等到解析器执行到它所在代码行,才会真正被解释执行.
alert(sum(10,10)); //20
function sum(num1,num2){
return num1 + num2;
}alert(sum(10,10)); //错误
var sum = function(num1,num2){
return num1 + num2;
};作为值的函数
因为js中的函数名本身就是变量,所以可以作为值来使用.
function a(ag){
return ag+10;
}function b(ag){
return ag;
}alert(b(a(10))); //20function callSomeFunction(someFunction,someArgument){
return someFunction(someArgument);
}function add10(num){
return num + 10;
}
var re = callSomeFuntion(add10,10); //add10不加()不会执行
alert(re); //20
闭包指在一个函数里有权调用另一个函数的变量。function a(aname){
return function(arg1,arg2){
var kk = arg1[aname];
alert(kk);
}
}
//把匿名函数赋给blm
var blm=a('aname');
//调用匿名函数
blm({aname:'ok'});
//把匿名函数释放,a函数才能释放内存
blm =null;
闭包会携带包含它的函数里面的活动对象,所以函数调用完并不会释放内存,必须释放闭包才行