摘要:js的数据类型有种划分方式为 原始数据类型和 引用数据类型。javascript
原始数据类型 存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。栈区包括了 变量的标识符和变量的值。php
引用数据类型 存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。放在栈空间中的值是该对象存储在堆中的地址。html
按值传递(call by value)是最经常使用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。java
按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而再也不是副本。这意味着函数形参的值若是被修改,实参也会被修改。同时二者指向相同的值。ajax
按引用传递会使函数调用的追踪更加困难,有时也会引发一些微妙的BUG。json
按值传递因为每次都须要克隆副本,对一些复杂类型,性能较低。两种传值方式都有各自的问题。数组
typeof 运算符,返回一个字符串,
指示未经
计算的操做数的类型。
函数
var person,name; person = 'kn'; name=person; person='黑白'; console.log(person,name,typeof person)//黑白 kn string
person的改变没有改变name,说明 string 是按值传递的。赋值时建立一块新的内存空间oop
true
和 false
.null
与 Null
、NULL
或其余变量彻底不一样。42
或者 3.14159。
基本类型是不可变的(immutable),只有对象是可变的(mutable). 有时咱们会尝试“改变”字符串的内容,但在JS中,任何看似对string值的”修改”操做,实际都是建立新的string值。任何方法都没法改变一个基本类型的值, 性能
1 var str = "abc"; 2 str[0]; // "a" 3 str[0] = "d"; 4 console.log(str); //abc 5 6 var name = 'jozo'; 7 var upName=name.toUpperCase(); 8 console.log(upName,name); // 输出 'JOZO' 'jozo'
方法操做没法改变一个基本类型的值
1 var person = 'kn'; 2 person.age = 24; 3 person.method = function(){}; 4 5 console.log(person.age); // undefined 6 console.log(person.method); // undefined
上面代码可知,咱们不能给基本类型添加属性和方法
引用类型的值是可变的
1 var obj = {x : 0}; 2 obj.x = 100; 3 var o = obj; 4 o.x = 1; 5 console.log(obj.x)// 1, 被修改 6 o = {x:100}; //等同于从新赋值,从新开辟内存,不是修改 7 console.log(JSON.stringify(obj),JSON.stringify(o))//{"x":1} {"x":100} 8 obj.x; // 1, 不会因o = {"x":100}改变
引用类型的值是同时保存在栈内存和堆内存中的对象
javascript和其余语言不一样,其不容许直接访问内存中的位置,也就是说不能直接操做对象的内存空间,那咱们操做啥呢? 实际上,是操做对象的引用,
因此引用类型的值是按引用访问的。
准确地说,引用类型的存储须要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,
也能够说是该对象在堆内存的地址。
假若有如下几个对象:
var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};
则这三个对象的在内存中保存的状况以下图:
var person1 = {}; var person2 = {}; console.log(person1 == person2); // false
引用类型时按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同,那很明显,person1和person2在堆内存中地址是不一样的。
首先要明白什么实参什么是形参。
实参:能够是常量、变量、表达式、函数等, 不管实参是何种类型的量,在进行函数调用时,它们都必须具备肯定的值, 以便把这些值传送给形参。 所以应预先用赋值,输入等办法使实参得到肯定值。
形参:全称为“形式参数”是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传递的参数。
形参的做用是实现主调函数与被调函数之间的联系,一般将函数所处理的数据,影响函数功能的因素或者函数处理的结果做为形参。
function addNum(param) //相对于addNum方法来讲 param是形参 { param+=10; return param; } var num=10; var result=addNum(num); //相对于addNum方法来讲 num是实参 console.log(num); //10 console.log(result);//20
上面的例子中,当将 num做为实参传入方法 addNum是 param做为形参接受 并在方法体内使用,且num在全局中没用改变,但当实参为引用类型时
1 function fun(param) //相对于fun方法来讲 param是形参 2 { 3 param[0]=99; 4 return param; 5 } 6 var num=[10]; 7 var result=fun(num); //相对于fun方法来讲 num是实参 8 console.log(num[0]); //99 9 console.log(result);//[99]
在方法体内改变 形参将同时改变实参。这个是其余语言中不会存在的,例如php,须要操做引用时,使用 &地址符 在形参的时候声明
1 <?php 2 function fun($param) //相对于fun方法来讲 param是形参 function fun(&$param){} 3 { 4 $param[0]=99; 5 // return $; 6 } 7 $num=[10]; 8 fun($num); //相对于fun方法来讲 num是实参 9 var_dump($num); 10 /* 11 array (size=1) 12 0 => int 10 13 */ 14 15 ?>
思考: 正由于js中 function的形参若为引用类型时,能够影响实参! 推断 callback中参数原理
1 function fun(data,callback){ 2 var json=[1,2,3]; 3 callback(json) 4 } 5 6 var data=[]; 7 fun(data,function(result){ 8 data=result; 9 }) 10 console.log(data)//[1, 2, 3]
如上例子 在回调函数中修改了 变量 data
知识点一、 function 是一种数据类型,能够当作参数传递 二、数组是引用类型 三、引用类型的形参会影响实参
1 <body> 2 <button onclick='log()'>ajax</button> 3 </body> 4 <script> 5 function fun(data,callback){ 6 setTimeout(function(){ 7 var json=[1,2,3]; 8 callback(json) 9 },4000) 10 11 } 12 13 var data=[]; 14 fun(data,function(res){ 15 data=res; 16 }) 17 console.log(data)//[] 18 function log(){ 19 console.log(data)//[1, 2, 3] 4秒后输出 20 } 21 22 </script>
使用 setTimeout 模拟ajax请求!
参考地址: http://www.w3school.com.cn/js/pro_js_value.asp
http://www.qdfuns.com/notes/17660/7f82003c5ce92d39d19d6be0403f3f3b.html