数据类型(object)、表达式及一元操作符
数据类型
- Object类型:对象可以通过执行 new 操作符后跟要创建的对象类型的名称来创建,也可使用大括号定义对象
(1)var a=new Object();
(2)var obj={
name:“小明”,
age:18,
message:function(){
return “,学习成绩很好”;
}
}
原始与引用类型:
一、不可变的原始值
任何方法都无法更改一个原始类型的值:数字、字符串、布尔值、null、undefined;
对字符串类型的修改操作,只会返回一个新的字符串,原始字符串不会被修改;
原始值在做比较时,只要值相等,他们就是相等的。
二、可变的对象引用:数组、对象、函数等(对象(引用)类型的值是可以修改的)
通过点(.)访问对象的属性:obj.name;
通过点(.)访问对象的方法:obj.message()
注
- 可变不可变,指的是栈数据里存储的值的变化;
- 原始变量名也在栈地址里,原始值存在栈数据里;引用变量名在栈地址里,引用值存在堆数据里,而栈数据里再存储堆地址。
- 包含相同属性及相同值的两个对象类型的值是不相等的:我们通常将对象称为引用类型(reference type);依照术语叫法,对象值都是引用,对象的比较均是引用比较;所以,当且仅当他们引用同一个基对象时,才相等;
- 如果想比较两个对象或者数组的值是否相等,则需要比较他们的属性或元素;数组可以循环比较每一个元素
创建对象
<script type="text/javascript">
var obj1=new Object();//var obj1={}
obj1.name="张三";
obj1.jump=function(){
console.log("蹦蹦跳跳");
};
//对象,是大括号包裹起来的key-value 形式的数据格式
//key 与value 之间是冒号分隔,多个key-value 之间逗号分隔
var obj2={
name:"张三",
jump:function(){
console.log("蹦蹦跳跳");
},
age:24,
fmail:false}
document.write(obj2.name);
document.write(obj2.jump())
var a=123;
a.toString();
console.log(typeof obj2);//object
</script>
包装对象
只要引用了字符串的属性,JavaScript就会将字符串值通过调用new String()的方式转换成对象,这个对象继承了字符串(String)对象的方法,并被用来处理属性的引用。一旦属性引用结束,这个新创建的对象就会被销毁。数字和布尔值的方法:通过Number()和Boolean()构造函数创建一个临时对象。存取字符串、数字或布尔值的属性时创建的临时对象就是包装对象。( JavaScript会在必要时将包装对象转换成原始值)(null和undefined没有包装对象:访问它们的属性会造成一个类型错误(Uncaught TypeError)
可通过String(),Number(),Boolean()构造函数来显示创建包装对象:
var s=new String(“123”);
<p>
原因是:只要引用了字符串s的属性,JavaScript就会将字符串值通过调用new String(s)的方式转换成对象,这个对象继承了字符串(String)对象的方法,并被用来处理属性的引用。**一旦属性引用结束,这个新创建的对象就会被销毁**。
</p>
<script type="text/javascript">
var str="dgahflafl";
//在原始类型引用属性时,它会被隐式转换为一个临时对象(包装对象),进行属性引用
//一旦引用结束,该临时对象立即被销毁
//null和undefined 没有包装对象,所以不能用.toString()方法
console.log(str.length);
console.log(typeof str);//string
str.length=20;
console.log(str.length);
var s = "test";
s.len = 4;//给它设置一个属性
var t = s.len;//上一句用完就被销毁,所以这一句的s 是没有len 这个属性的
console.log(t);
</script>
原始类型和引用类型
<script type="text/javascript">
//原始类型:值不可更改,栈里
var str1="abc",str2="abc";
//原始类型只要值是相等的,两个变量肯定就相等
console.log(str1==str2);
console.log(str1===str2);
var obj={ name:"付世杰" }
obj.name="王建";
console.log(obj.name);
//引用类型:值可更改,堆里
var myobj1={ name:"李旭" },myobj2={ name:"李旭" };
//包含相同属性及相同值的两个对象类型的值是不相等的:
console.log(myobj1==myobj2);//false
var objTest={ age:24 };
var myObjTest=objTest;
objTest.age=30;
myObjTest={ age:30 };
console.log(objTest==myObjTest);//true
console.log(myObjTest.age);
</script>
作用域
- 作用域:全局作用域和函数作用域(又叫局部作用域)两种
-
- 全局作用域:全局作用域是最外围的一个执行环境,在web浏览器中,全局执行环境被认为是window对象。所有全局变量和函数都是作为window对象的属性和方法创建的。全局变量拥有全局作用域,在javascript代码中的任何地方都是有定义的。全局作用域直到应用程序退出例如关闭网页或浏览器时才会被销毁。
JS中声明的全局变量是全局对象的属性;函数体内不使用var声明而直接赋值的变量当做全局变量;
- 全局作用域:全局作用域是最外围的一个执行环境,在web浏览器中,全局执行环境被认为是window对象。所有全局变量和函数都是作为window对象的属性和方法创建的。全局变量拥有全局作用域,在javascript代码中的任何地方都是有定义的。全局作用域直到应用程序退出例如关闭网页或浏览器时才会被销毁。
- 全局属性:如undefined、Infinity、NaN等;
- 全局函数:如parseInt()、eval()、isNaN()、toFixed()等;
- 构造函数:如Array()、String()、Date()等;
- 全局对象:如Math,补充:Math.ceil(x)与Math.floor(x),向上向下取整等;
(写程序时最好把这些全局对象当做保留字,避免出现意外错误。)
-
- 局部作用域:在函数内(var声明)的变量只在函数体内有定义;它们只在函数体内有定义。函数作用域中的所有代码执行完毕后,该作用域被销毁,保存在其中的所有变量和函数定义也随之销毁。
- 优先级:在函数体内,局部变量的优先级高于同名的全局变量,如果在函数内声明的一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量遮盖。
注: 函数里边的能访问外边的,优先访问自己函数里边的;函数外边的不能访问函数里边的
<script type="text/javascript">
// 作用域:分为全局作用域和局部作用域
//局部没有var的是局部,var为全局
// 全局作用域:最外围的执行环境,
// window对象==最外围的执行环境
// 在最外围声明的变量和函数,是作为window 对象的属性和方法存在的
// 所以,在全局作用下声明的函数和变量,就可以在任何地方都能访问到
var a=100;
b=10000;
function myfn(){console.log("hello world") }
window.myfn();
// 函数作用域就是一个局部作用域
function fn(){
var str1="hello";
str2="kitty";
console.log(str1,str2);}
fn();
// console.log(str1);//报错
str2="mouse";
console.log(str2);//函数体内没有用var 声明的变量---全局变量
fn();
console.log(str2);//养成规范,函数体内用var 去声明变量
//它们是局部变量,作用域是局部性的。函数参数也是局部变量,它们只在函数体内有定义。函数作用域中的所有代码执行完毕后,该作用域被销毁,保存在其中的所有变量和函数定义也随之销毁。
var myTest=false;
function fnTest(){
//局部作用域下优先访问局部变量
var myTest=true;
console.log(myTest);//true
}
fnTest();
//全局作用域下访问全局作用域
console.log(myTest);//false
var myTest1=false;
function fnTest1(){
//在局部作用域下优先访问局部变量,当局部作用域下没有该变量时,则访问上一层作用域(全局作用域)
myTest1=true;
console.log(myTest1);//true
}
fnTest1();
console.log(myTest1);//true
//函数体内可以访问函数上一层的变量,而函数外部无法访问函数内部的局部变量
</script>
表达式
一、原始表达式
1.原始表达式不可再分割,是最小单位的表达式
2.原始表达式包含直接量、关键字(保留字)和变量名
二、数组初始化表达式
1.可以简单理解为:数组直接量
2.数组初始化表达式:由中括号([])和其内用逗号(英文状态 ,)分隔开的列表构成
3.初始化的结果是创建一个新的数组;数组的元素是逗号分隔开的表达式的值
4.“数组初始化表达式”中的“元素”也可以是“数组初始化表达式”,即多维数组;(数组直接量的语法允许有可选的结尾的逗号)
三、对象初始化表达式
1.可以简单理解为:对象直接量
2.对象初始化表达式:由花括号({})和其内用逗号(英文状态 ,)分隔开的列表构成;
3.初始化的结果是创建一个新的对象; 对象的属性是逗号分隔开的表达式的值; 属性包括属性名和属性值,属性名和属性值之间用冒号隔开
4.“对象初始化表达式”中的“元素”也可以是“对象初始化表达式”,可以任意层级嵌套
四、函数定义表达式
1.可以简单理解为:函数直接量
2.表达式的值是这个新定义的函数
五、 属性访问表达式(属性访问表达式得到一个对象的属性或者一个数组的元素值)
1.有两种访问方式:点(.)、中括号([])
2.点的访问方式更方便,中括号的访问方式使用所有情况
六、调用表达式(调用表达式fn() 是执行函数或方法的语法表示)
1.如果调用的函数或方法有返回值,则表达式的值就是该返回值
2.如果调用的函数或方法没有返回值,则表达式的值是undefined
3.简单理解就是函数或方法名称后面跟上小括号代表执行
七、对象创建表达式(由函数调用表达式延伸而来,前面加个new即可)
1.如果不需要传递参数,函数后面的小括号可以省略
2.如果调用的函数或方法没有返回值,则表达式的值是undefined
3.简单理解就是函数或方法名称后面跟上小括号代表执行
算术表达式
- +:数字相加 或 字符串连接
如果其中一个操作数是对象,则JavaScript会自动把他转成原始类型的值;
如果其中一个操作数是字符串的话,则另一个也会转成字符串,然后进行字符串拼接;
如果两个操作数都是数字,则进行加法运算; - 减乘除取余----运算结果全都是number类型
数组初始化表达式
<script type="text/javascript">
var arr=[1,,,3,{},[],false,"fks"];
console.log(arr.length)
console.log(arr[1]);
arr[1]=5;
console.log(arr[1]);
arr.length=10;//引用类型,都是特殊的Object
console.log(arr.length);//10
var str="123";
str.length=10;//包装对象
console.log(str.length);//3
var obj={
name:"付世杰",
age:4,
say:function(){
console.log("会说话");
},
family:{
father:"付爸爸",
isBrother:false
},
grade:[67,78,80,85,95]
}
console.log(obj.name,obj.family.isBrother,obj.grade[1])
//数组最后的逗号表示结束意义
var a1 = [];
var a2 = [,];
var a3 = [,,];
var a4 = [1,,];
var a5 = [,1,];
var a6 = [,,1];
var a7 = [1,,3];
console.log(a1.length,a2.length)
</script>
js 属性访问表达式
<script type="text/javascript">
var a = {name:'yourname', age:22};
var b = {
p1:{name:'华子', age:22},
p2:{name:'华耀', age:25},
p3:{name:'华赓', age:24}
};
var c = [1,2,3,4,'a','b','c'];
var d = [['a','b','c'],['d','e','f'],['g','h']];
console.log(a.age);//22
console.log(b.p2['name']); //对象用中括号访问时,注意加引号!
console.log(c[4]); //a
console.log(d[2][1]); //h
var obj={
name:"付世杰",
age:4,
say:function(){
console.log("会说话");
},
family:{
father:"付爸爸",
isBrother:false
},
grade:[67,78,80,85,95]
}
var property=prompt("请输入你想查看的信息");
console.log(obj.property);//访问对象没有的属性不会报错,值是undefined
document.write(obj[property])
var str="123";
str.len=4;
console.log(str.len);//uundefined
function myfn(){}
</script>
函数调用
<script type="text/javascript">
function fn(){
console.log("fahk");
return console.log(fn);
}
//函数调用2种
//函数new
//函数()
console.log(fn);//打印函数体
//当函数没有返回值时,函数调用表达式的值是undefined
console.log(fn());//函数调用表达式
</script>
问题总结
<script type="text/javascript">
//对象,大括号括起来,key-value,key与value 之间冒号做分隔,多个key-vlue之间逗号分隔
var obj={
son:"miao",
dayin:console.log("11111"),
he:100,
fn:function(){
console.log("这是我在obj里写的函数(方法)")
}
}
console.log(obj.dayin);
console.log(obj.fn);
</script>
操作符
一元操作符:只能操作一个值的操作符叫做一元操作符。一元操作符是 ECMAScript 中最简单的操作符。
递增和递减操作符(前置型和后置型):前置操作符,先加减后用;后置操作符,先用后加减
递增和递减操作符遵循下列规则:
在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减 1 的操作。字符串变量变成数值变量。
在应用于一个不包含有效数字字符的字符串时,将变量的值设置为 NaN。字符串变量变成数值变量。
在应用于布尔值 false 时,先将其转换为 0 再执行加减 1 的操作。布尔值变量变成数值变量。
在应用于布尔值 true 时,先将其转换为 1 再执行加减 1 的操作。布尔值变量变成数值变量。
在应用于浮点数值时,执行加减 1 的操作。
在应用于对象时,先调用对象的 valueOf()方法(后面章节将详细讨论)以取得一个可供操作的值。然后对该值应用前述规则。如果结果是 NaN,则在调用 toString()方法后再应用前述规则。对象变量变成数值变量。
一元加和减操作符 :
一元加操作符以一个加号(+)表示,放在数值前面,对数值不会产生任何影响;在对非数值应用一元加操作符时,该操作符会像 Number()转型函数一样对这个值执行转换;布尔值 false 和 true 将被转换为 0 和 1,字符串值会被按照一组特殊的规则进行解析,而对象是先调用它们的 valueOf()和(或) toString()方法,再转换得到的值。
一元减操作符主要用于表示负数,在将一元减操作符应用于数值时,该值会变成负数。而当应用于非数值时,一元减操作符遵循与一元加操作符相同的规则,最后再将得到的数值转换为负数。