JavaScript的组成
1、ECMAScript:标准
2、DOM:文档对象模型(操作网页)
3、BOM:浏览器对象模型(操作浏览器)
输出语句
<script type="text/javascript">
// 控制浏览器弹出警告框
alert("这是我的第一行JS代码");
// 在网页中写点东西(网页就是一个文件)(相当于在body中写了东西)
document.write("aaaaaaa");
// 向控制台输出一个内容
console.log("bbbbbbb");
</script>
编写位置
1、直接在html文件中添加script标签进行编写
2、引入外部js文件
3、写在标签的属性中
<!-- 可以引入外部JS
可以在不同的页面中同时使用,也可以利用到浏览器的缓存机制
推荐使用
script标签一旦用于引入外部文件,就不能再编写代码了,计时编写了浏览器也会忽略
如有需要可以再创建一个script标签-->
<script src="outerJavaScript.js"></script>
<script>alert("这是内部js")</script>
<body>
<!--将js代码写在属性中,耦合度较高,不推荐-->
<!--可以将js代码编写到标签的onclick属性中-->
<button onclick="alert('已点击按钮')">点击</button>
<!--可以将js代码编写到超链接的href属性中-->
<a href="javascript:alert('已点击超链接')">超链接</a>
<!--希望点击超链接时不做出任何反应-->
<a href="javascript:;">超链接2</a>
</body>
基本语法
/*多行注释*/
// 单行注释
/*
* 1、js中严格区分大小写
* 2、js中每个语句已分号结尾(不写分号浏览器会自动添加,但会消耗系统资源,而且有时候会加错分号)
* 3、js中会忽略多个空格和换行,所以可以利用空格和换行对代码进行格式化(美化)
*/
字面量和变量
<script>
/*
* 字面量:一些不可改变的量(如:1,2,3……)
* 可以直接使用,但一般不会直接使用字面量
* 变量:可以用来保存字面量,且变量值可以任意改变,更加方便使用
*/
//声明变量:var;并赋值
var x=123;
console.log(x);
</script>
标识符
<script>
/*
* 在js中所有的可以由我们自主命名的都可以称为标识符
* 如:变量名,函数名,属性名
* 命名规则:
* 1、标识符中可以含有字母、数字、下划线(_)、$
* 2、标识符不能以数字开头
* 3、标识符不能是js中的关键字或保留字
* 4、标识符一般采用驼峰命名法(首字母小写,剩下每个单词的开头字母大写 helloWorld)
*
* js底层保存标识符时实际上是采用Unicode编码,所以理论上来说,所有utf-8中含有的内容都可以作为标识符
*/
</script>
数据类型
<script>
/*
* 字面量的数据类型
* js中共有6中数据类型:
* String 字符串
* Number 数值
* Boolean 布尔值
* Null 空值
* Undefined 未定义
* Object 对象
* 其中前5种属于基本数据类型,第6种属于引用数据类型
*/
/*
* String:
* 字符串用双引号或单引号引起来,但不要混用;
* 引号不能嵌套,双引号里不能放双引号,单引号里不能放单引号
* 字符串中使用\进行转义
* \"代表"
* \'代表'
* \n代表换行
* \t代表制表符
* \\代表\
*/
var str="他说:‘无所谓’";
console.log(str);
var str2="他说:\"无所谓啊\"";
console.log(str2)
/*
* Number:js中所有数值都是Number类型(整数、浮点数)
* typeof 变量名:检查变量的类型
* js中可以表示的数字的最大值:Number.MAX_VALUE,Number.MIN_VALUE则表示零以上的最小值
* 若表示的数字超过最大值,则返回Infinity,表示正无穷
* Infinity代表一个字面量
* NaN:特殊数字(字面量),代表not a number
* 在js中整数的运算基本可以保证精确,但若进行浮点运算,可能得到一个不精确的结果(不要使用js进行对精确度要求较高的运算)
*/
var a=123.45;
console.log(typeof a);
console.log(Number.MAX_VALUE);
console.log(typeof Infinity)
var b="ac" * "bd";
console.log(b);
console.log(typeof b);
var c=0.1+0.2;
console.log(c);
/*
* Boolean:true false
*/
/*
* Null:null
* null用来表示为空的对象,用typeof检查null,返回object
*/
var d=null;
console.log(typeof d);
/*
* Undefined:undefined
* 声明一个变量且未赋值时,即为undefined
*/
var e;
console.log(typeof e);
</script>
强制类型转换
<script>
//类型转换主要指将其他数据类型转换为String,Number,Boolean
/*
* 将其他数据类型转换为String:
* 方式1:调用toString()方法 此方法不会影响到原变量,它会返回转换结果(null和undefined不能调用此方法)
* 方式2:调用String()函数 此函数可以将四种基本数据类型转换为String类型
*/
//方式1
var a=123;
var s = a.toString();
console.log(typeof a);
console.log(typeof s);
//方式2
var b=123;
var s2 = String(b);
console.log(typeof s2);
/*
* 将其他数据类型转换为Number:
* 方式1:调用Number()函数
* String转Number:若为纯数字的字符串,则直接转换为数字;若字符串中有非数字的内容,则转换为NaN;若为空串,则转换为0
* Boolean转Number:true转换为1,false转换为0
* Null转Number:null转换为0
* Undefined转Number:undefined转换为NaN
* 方式2:parseInt() 把一个字符串转换为整数(如果字符串中的第一位就不是数字,则返回NaN)
* parseFloat() 把一个字符串转换为浮点数(如果字符串中出现两个小数点,则只取前面一个)
* 若对非String使用上述两种方法,则会先将其转换为String,再转换为Number
*/
//方式1
var c="123";
var number = Number(c);
console.log(typeof number);
//方式2
var d="123px";
var number2 = parseInt(d);
console.log(number2);
var e="qq123px";
var number3 = parseInt(e);
console.log(number3);
var f="123.4px";
var number4 = parseInt(f);
console.log(number4);
var g="123.456px";
var number5 = parseFloat(g);
console.log(number5);
/*
* 将其他数据类型转换为Boolean:
* 调用Boolean()函数
* Number转Boolean:除了0和NaN,其他都是true
* String转Boolean:除了空串,其他都是true
* Null和Undefined转Boolean:null和undefined都转换为false
* 对象也会转换为true
*/
var q=0;
var p = Boolean(q);
console.log(p);
</script>
<!-- 在js中表示一些其他进制的数字-->
<script>
/*
* 16进制:0x开头
* 8进制:0开头
* 2进制:0b开头(不是所有浏览器都支持)
*
* 像“070”这种字符串在用parseInt转换为Number时,有些浏览器会用八进制解析,有些则用十进制解析
* 若一定要用十进制解析,则parseInt("070",10)
*/
var m="070";
var n = parseInt(m,10);
console.log(n);
</script>
运算符(操作符)
<!-- 算术运算符-->
<script>
/*
* typeof也算一种运算符,获得一个值的类型,它会将该值的类型以字符串的形式返回
* 二元运算符:
* +
* -
* *
* /
* %
*/
/*
* +:
* 当对非Number类型的值进行运算时,会将这些值转换为Number然后再运算:true=1;false=0;null=0
* 任何值与NaN做运算,结果都为NaN
* 两个字符串相加,则会做拼接,变成一个字符串
* 任何值与字符串做加法运算,都会先转换成字符串,再做拼接(为任意数据类型加一个空串(“”),即可把该数据类型转换为String)→(隐式类型转换,由浏览器自动完成,本质也是调用String()函数)
*
*/
console.log(true+1);
console.log(false+1);
console.log(null+1);
console.log(NaN+1);
console.log("123"+"456");
console.log(typeof ("123"+456));
var a=123;
a=a+"";
console.log(typeof a);
console.log(a);
console.log(1+2+"3");//33
console.log("1"+2+3);//123
/*
* -:
* 除了加法,其他关于字符串的运算都会把字符串转换成Number再进行运算
*/
console.log(100-"1");//99
console.log(100-undefined);//NaN
/*
* *:
* 任何值做- * /运算都会自动转换为Number(通过为一个值-0;*1;/1将其转换为Number )→(隐式类型转换,本质和Number()函数一样)
*/
console.log(2*"2");
console.log(2*undefined);//NaN
console.log(2*null);//0
/*
* %:取余运算
*/
</script>
<script>
/*
* 一元运算符:只需要一个操作数,比如typeof
* +:正号
* -:负号
* ++:自增
* --:自减
* 对于非Number类型的值,先转换成Number,再做运算(可以对一个其他的数据类型使用+使它变成Number类型,本质与Number()函数一样)→(隐式类型转换)
* 后++(a++)和前++(++a):无论是a++还是++a,都会立即使原变量(a)的值自增1;
* a++的值等于原变量的值(自增前的值);++a的值等于原变量自增后的值
*/
var a=123;
console.log(+a);
console.log(-a);
var m=true;
console.log(-m);
console.log(+m);
var n=1;
console.log(n++);//1
console.log(n);//2
var q=1;
console.log(++q);//2
console.log(q);//2
var d=20;
console.log(d++ + ++d + d);//20+22+22=64
</script>
<!-- 逻辑运算符-->
<script>
/*
* 逻辑运算符:
* !:非
* 对非布尔值进行非运算,会先转化成布尔值,再运算(可以为任意数据类型做两次非运算,将其转换为布尔值)→(隐式类型转换,本质与Boolean()函数一样)
* &&:与
* js中的与为短路与,若第一个值为false,则直接返回false;若第一个值为true,才会检查第二个值
* ||:或
* js中的或为短路或,若第一个值为true,则直接返回true;若第一个值为false,才会检查第二个值
*/
var a=10;
console.log(!a);
</script>
<script>
/*
* && ||的非布尔值情况
* 对非布尔值进行与或运算时,会先将其转换为布尔值,然后再运算,并且返回原值
* 与运算:如果第一个值为true,则必然返回第二个值;如果第一个值为false,则直接返回第一个值(与短路相符合)
* 或运算:如果第一个值为false,则必然返回第二个值,如果第一个值为true,则直接返回第一个值
*
*/
console.log(1&&2);//2
console.log(0&&1);//0
console.log(NaN&&0);//NaN
console.log(0&&NaN);//0
</script>
<!-- 赋值运算符-->
<script>
/*
* =:将右侧值赋给左侧变量
* +=:a+=5等价于a=a+5
* -=:
* *=:
* /=:
* %=:
*/
</script>
<!-- 关系运算符-->
<script>
/*
* 比较两个值之间的大小关系,若关系成立则返回true,不成立则返回false
* >
* >=
* <
* <=
* ==
* !=
* ===:全等(与==类似,但不会做自动类型转换,若两个值类型不同,直接返回false)
* !==:不全等(与!=类似,但不会做自动类型转换,若两个值类型不同,直接返回true)
* 对于非数值进行比较时,会先将其转换为数字,再进行比较
* 任何值与NaN做比较都是false
* 如果符号两侧的值都是字符串,不会将其转换为数字进行比较,会分别比较每个字符的Unicode编码
* 比较时诸位进行比较,如果相同则比较下一位(可以借用它对英文进行排序)
*/
console.log(1>"hello");//false
console.log("11"<"5");//true
console.log("a"<"b");//true 97<98
console.log("bbc"<"b");//false
/*
* 当使用==比较两个值时,如果值类型不同,则会自动进行类型转换,转换为相同类型时再进行比较(转换为哪种类型不确定)
* undefined衍生自null,所以undefined==null
* NaN不与任何值相等,包括它本身
* isNaN():检查一个值是否是NaN,如果该值是NaN,则返回true,否则返回false
*/
console.log("1"==1);//true
console.log(true == "1");//true
console.log(null==0);//false
console.log(null==undefined);//true
console.log(NaN==NaN);//false
var a=NaN;
console.log(isNaN(a));//true
/*
* !=会对变量进行自动类型转换,如果转换后相等会返回false
*/
console.log("1"!=1);//false
console.log("123"===123);//false
console.log(null===undefined);//false
console.log(1!=="1");//true
</script>
<!-- Unicode编码-->
<script>
/*
* 在字符串中使用转义字符输入Unicode编码:\u四位编码
*
*/
console.log("\u0032");//2
console.log("\u2620");//骷髅头
</script>
<body>
<!--在网页中使用Unicode编码:&#编码(这里的编码需要是十进制)-->
<h1 style="font-size: 100px">☠</h1>
<h1 style="font-size: 100px">⚀</h1>
</body>
<!-- 条件运算符(三元运算符)-->
<script>
/*
* 语法:条件表达式?:语句1:语句2;
* 执行时,首先对条件表达式进行求值,如果该值为true,则执行语句1,并返回执行结果;
* 如果该值为false,则执行语句2,并返回执行结果
* 如果条件表达式的求值结果是一个非布尔值,会将其转换为布尔值然后再运算
*/
var a=10,b=20,c=30;
var max=a>b?a:b;
alert(max);
</script>
流程控制语句
<!-- 流程控制语句-->
<script>
/*
* 语句的分类:条件判断语句;条件分支语句;循环语句
*/
/*
* 条件判断语句(if语句):
* 语法:if(条件表达式){语句}else{语句}
* if(条件表达式){语句}else if(条件表达式){语句}else{语句}
* 该语句中,只会有一个代码块被执行,其余的不执行
* 练习:对输入的三个数按照从大到小排序
*/
//prompt():弹出一个提示框,里面包含可以输入内容的文本框,需要一个字符串作为参数;输入内容作为String类型的返回值返回
var s1 = prompt("请输入第一个数:");
var s2 = prompt("请输入第二个数:");
var s3 = prompt("请输入第三个数:");
var num1 = Number(s1);
var num2 = Number(s2);
var num3 = Number(s3);
if(num1>num2 && num1>num3){
if(num2>num3){
alert(num1+","+num2+","+num3)
}else {
alert(num1+","+num3+","+num2);
}
}else if (num2>num1 && num2>num3){
if(num1>num3){
alert(num2+","+num1+","+num3);
}else {
alert(num2+","+num3+","+num1);
}
}else if (num3>num1 && num3>num2){
if(num1>num2){
alert(num3+","+num1+","+num2);
}else {
alert(num3+","+num2+","+num1);
}
}
/*
* 条件分支语句(switch语句):
* 语法:switch(条件表达式){
* case 表达式:语句;break;
* default:语句;break;
* }
* 执行流程:依次将case后的表达式与switch后的条件表达式进行全等比较
* 若比较结果为true,则从当前case处开始执行代码,直到遇到break,如果没有break,则当前case后的所有代码都会执行
* 若比较结果为false,则继续向下比较
*/
var num=Number(prompt("请输入:"));
switch (num) {
case 1:alert("输入的是1");break;
case 2:alert("输入的是2");break;
default:alert("输入的不符合要求");break;
}
//另一种方法是grade/10,然后case取值6,7,8,9,10;值得注意的是,js中99/10=9.9,而不是9,所以需要取整:parseInt(grade/10)
//还有一种方法:switch(true){case grade>=60:alert("合格");break;default:alert("不合格");break;}
var grade=Number(prompt("请输入成绩(0-100):"));
var a=0;
if(grade<=0 || grade>100){
alert("非法输入");
}else if (grade>=60){
a=1;
}else if (grade<60){
a=2;
}
switch (a){
case 1:alert("合格");break;
case 2:alert("不合格");break;
}
</script>
<script>
/*
* 循环语句:while循环;do...while循环;for循环
* while循环(先判断再执行):
* 语法:while(条件表达式){语句} (可以用break退出while循环)
* do...while循环(先执行再判断,可以保证循环体至少执行一次,while不行):
* 语法:do{语句}while(条件表达式)
* for循环:
* 语法:for(初始化表达式;条件表达式;更新表达式){语句}
* 三个部分的表达式可以省略,也可以写在外面;都不写,只有两个分号,则代表死循环
*/
var i=0;
while (i<10){
document.write(i+"<br>");//网页换行用<br>,使用\n是无效的
i++;
}
var m=20;
do {
document.write(m+"<br>");
m++;
}while (m<30)
var money=1000,year=0;
while (money<=5000){
money=money*1.05;
year++;
}
document.write("从1000增长到5000,需要花费"+year+"年");
/*var inputNum=Number(prompt("请输入一个数字(0-9)"));
while(inputNum<0 || inputNum>9){
alert("输入不合法,请重新输入:");
inputNum=Number(prompt("请输入一个数字(0-9)"));
}
alert("输入的数字为:"+inputNum);*/
while (true){
var inputNum=Number(prompt("请输入一个数字(0-9)"));
if(inputNum>=0 && inputNum<=9){
alert("输入的数字为:"+inputNum);
break;
}else {
alert("输入不合法,请重新输入:");
}
}
for (let j = 100; j < 110; j++) {
document.write(j+"<br>");
}
</script>
<!-- break和continue-->
<script>
document.write("====================="+"<br>");
/*
* break可以用来退出switch或循环语句
* if语句不能单独使用break和continue,但如果是嵌套在循环语句中的if,就可以用
* 可以为循环语句创建一个label,来标识当前的循环(label:循环语句)
* 在break后面跟一个label,将会结束指定的循环
*/
outer:
for (let i = 0; i < 5; i++) {
document.write("外层"+i+"<br>");
for (let j = 0; j < 5; j++) {
break outer;
document.write("内层"+j+"<br>");
}
}
</script>
<script>
/*
* continue用来跳过当次循环
* continue默认只对离他最近的循环起作用
* continue label:终止指定循环下的当次循环
*/
document.write("<br>");
aaa:
for (let i = 0; i < 5; i++) {
if (i==2){
continue;
}
//document.write(i+" ");
if (i==3){
continue aaa;
}
document.write(i+" ");
}
</script>
对象
<!-- 对象:复合的数据类型,在对象中可以保存多个不同数据类型的属性-->
<script>
/*
* 对象的分类:
* 1、内建对象:由ES标准中定义的对象,在任何ES的实现中都可以使用(Math,String,Number,Boolean,Object,Function……)
* 2、宿主对象:由JS的运行环境提供的对象,目前主要指浏览器提供的对象(BOM,DOM)
* 3、自定义对象:由开发人员自己创建的对象
*/
//创建对象
var obj=new Object();//new调用的是构造函数(constructor),构造函数是专门用来创建对象的函数
//向对象中添加属性(语法:对象.属性名=属性值)(如果读取对象中不存在的属性,则返回undefined)
obj.name="张三";
obj.gender="男";
obj.age="18";
console.log(obj);
//读取对象的属性(语法:对象.属性名)
console.log(obj.name);
//修改对象的属性值(对象.属性名=新属性值)
obj.name="李四";
console.log(obj.name);
//删除对象的属性(语法:delete 对象.属性名)
delete obj.name;
</script>
<script>
/*
* 属性名:
* 对象的属性名不强制要求遵守标识符的规范
* 如果需要使用特殊的属性名,不能用.的方式,而是用:对象["属性名"]=属性值(读取时同样采取该方式)
* 可以直接在[]中传递一个变量,变量值等于属性名
*/
var obj2=new Object();
obj2.var="hello";
console.log(obj2.var);//尽量不用,没有意义
obj2["123"]=456;
console.log(obj2["123"]);
obj2["hello"]="你好";
h="hello";
console.log(obj2[h]);
</script>
<script>
/*
* 属性值:
* JS对象的属性值,可以是任意的数据类型
* in:通过该运算符可以检查一个对象中是否含有指定属性,有则返回true,无则返回false
* 语法:“属性名” in 对象
*/
var obj3=new Object();
var obj4=new Object();
obj3.name="王五";
obj4.test=obj3;
console.log(obj4.test);
console.log(obj4.test.name);
console.log("test" in obj4);
</script>
<script>
/*
* 基本数据类型:String,Number,Boolean,Null,Undefined
* 引用数据类型:Object
*
* JS中的变量都保存在栈内存中:
* 基本数据类型的值直接在栈内存中存储,值与值之间独立存在,修改一个变量不会影响其他的变量;
* 每创建一个对象就会在堆内存中开辟处一个新空间
* 对象在栈内存中保存的是它的对象名和该对象的内存地址(对象的引用),而它的整体属性保存在堆内存中
* 如果两个变量保存的是同一个对象引用,当一个变量修改属性时,另一个也会受到影响
*
* 当比较两个基本数据类型时,比较的就是值;比较两个引用数据类型时,比较的是内存地址
*/
var a=123;
var b=a;
a++;
console.log(a);//124
console.log(b);//123
var obj5=new Object();
obj5.name="杨六";
var obj6=new Object();
obj6=obj5;
obj5.name="陈七";
console.log(obj5.name);//陈七
console.log(obj6.name);//陈七
console.log(obj5==obj6);//true
var obj7=new Object();
obj7.name="one";
var obj8=new Object();
obj8=obj7;
obj7.name="two";
obj8=null;//相当于将obj8指向obj7的内存地址断开
console.log(obj7);//two
console.log(obj8);//null
var obj9=new Object();
obj9.name="aa";
var obj10=new Object();
obj10.name="aa";
console.log(obj9==obj10);//false
</script>
<script>
/*
* 对象字面量:在创建对象时,可以直接指定对象中的属性
* 语法:{属性名:属性值,属性名:属性值,……};
* 对象字面量的属性名可以加引号也可以不加,如果要使用一些特殊的名字,则必须加引号
*/
var object={};
object.name="bb";
console.log(object.name);
var object2={
name:"cc",
age:18,
gender:"male",
test:{name:"qq"}
};
console.log(object2);
</script>
函数
<!-- 函数-->
<script>
/*
* 函数也是一个对象
* 使用typeof检查一个函数对象时,会返回function
*/
/*
用构造函数创建函数对象(不推荐)
//创建一个函数对象,将要封装的代码以字符串的形式传递给构造函数
var fun=new Function("console.log(\"这是第一个函数\")");
//调用函数(语法:函数对象())
fun();
*/
/*
* 使用函数声明来创建函数
* 语法:function 函数名(形参1,形参2……){语句}
*/
function fun() {
console.log("函数");
}
fun();
/*
* 使用函数表达式来创建一个函数
* 语法:var 函数名=function (形参1,形参2,……){语句}
*/
var fun2=function () {
console.log("将匿名函数赋值给变量fun2");
}
fun2();
</script>
<script>
/*
* 函数的参数(形参)
* 调用函数时解析器不会检查实参的类型,所以要检查是否接收到非法参数
* 调用函数时解析器不会检查实参的数量,多余的实参不会被赋值;若实参的数量少于形参的数量,没有对应实参的形参将是undefined
*/
function sum(x,y) {
console.log(x+y);
}
sum(4,5);//9
sum(1,"hello");//1hello
sum(1,2,3,"hello");//3
sum(1);//NaN(x=1,y=undefined)
//参数过多时,可以用对象作为参数
function information(people) {
return document.write("姓名:"+people.name+",性别:"+people.gender+",年龄:"+people.age+"<br>");
}
var person={
name:"yyds",
gender:"female",
age:18
}
information(person);
//实参也可以传(匿名)函数:fun(function () {})
</script>
<script>
/*
* 函数的返回值
* 使用return设置返回值
* 语法:return 值;
* 在函数中,return后的语句不执行,整个函数直接退出;不写return返回undefined
* return;等价于return undefined;
* return后可以跟任意类型的值,包括对象(包括函数)
* alert()函数没有返回值
*/
function mutiply(x,y,z) {
var result=x*y*z;
return result;
}
console.log(mutiply(1,2,3));
</script>
<script>
//定义一个函数,判断一个数字是否是偶数,如果是返回true,否则返回false
function evenNumber(x) {
if (x%2==0){
return true;
}else {
return false;
}
}
var inputNum=Number(prompt("请输入一个数:"))
document.write("是否是偶数:"+evenNumber(inputNum)+"<br>");
//定义一个函数,可以根据半径计算一个圆的面积,并返回计算结果
function circle(r) {
return Math.PI*r*r;
}
var radius=Number(prompt("请输入圆的半径:"));
document.write("圆的面积为:"+circle(radius)+"<br>");
/*
* show(circle(1));调用的是函数
* show(circle);调用的是函数对象
*/
function show(msg) {
alert(msg);
}
show(circle(1));//3.141592653589793
show(circle);//function circle(r) {return Math.PI*r*r;}
</script>
<script>
/*
* 立即执行函数;函数定义完立即被调用
* 立即执行函数往往只会执行一次
* 语法:函数对象();或者(匿名函数)();
*/
(function () {
alert("这是一个匿名函数");
})();
(function f(a,b) {
console.log(a);
console.log(b);
})(12,34);//12 34
</script>
<!-- 方法-->
<script>
/*
* 方法:
* 对象的属性值可以是任何的数据类型,包括函数
* 如果一个函数作为一个对象的属性保存,则称这个函数是该对象的方法,调用该函数即调用该对象的方法
*/
var obj=new Object();
obj.name="zhangsan";
obj.age=18;
obj.sayName=function () {
document.write(obj.name+"<br>");
}
function f() {
document.write(obj.name+"<br>");
}
obj.sayName();//方法 zhangsan
f();//函数 zhangsan
var obj2={
name:"lisi",
age:19,
gender:"male",
sayName:function () {
document.write(obj2.name+"<br>");
}
}
obj2.sayName();//lisi
/*
* 枚举对象中的属性
* 语法:for(var 变量 in 对象){ }
* for...in...语句:对象中有几个属性,循环体就会执行几次
* 每次执行时,会将对象中的属性名赋给变量
*/
for (var n in obj2){
document.write("属性名:"+n+"属性值:"+obj2[n]+"<br>");//不能用obj2.n,因为会变成去obj2中寻找n这个属性,得到的结果只能是undefined
}
</script>
<!-- 作用域-->
<script>
/*
* 作用域:全局作用域;函数作用域
* 1、全局作用域:直接编写在script标签中的代码
* 在页面打开时创建,在页面关闭时销毁
* 在全局作用域中有一个全局对象window,代表浏览器窗口,由浏览器创建,可以直接使用
* 在全局作用域创建的变量都会作为window的属性保存
* 在全局作用域创建的函数都会作为window的方法保存
* 全局作用域中的变量都是全局变量,在页面的任意部分都可以调用
* 2、函数作用域:
* 调用函数时创建函数作用域,函数执行完后,函数作用域销毁
* 每调用一次函数,就会创建一个新的函数作用域,他们之间相互独立
* 在函数作用域中可以访问到全局变量,在全局作用域中不能访问函数作用域的变量
* 在函数作用域中操作一个变量时,会现在自身作用域中寻找,有就直接使用;没有才向上一级作用域中寻找,直到找到全局作用域,如果全局作用域也没有,则报错
* 在函数中访问全局变量,可以使用window对象
* 在函数作用域中也有声明提前的特性,使用var声明的变量,会在函数中所有代码执行之前被声明;函数声明也会咋函数中所有代码执行之前被声明
* 在函数中,不使用var声明的变量都会成为全局变量
* 定义形参相当于在函数作用域中定义了变量
*/
/*
* 变量的声明提前:
* 使用var声明的变量,会在所有的代码执行之前被声明
* 如果声明变量时不使用var,则变量不会被提前声明
* /
/*
console.log(a);//undefined
var a=123;
console.log(a);//error
a=123;
*/
/*
* 函数的声明提前:
* 使用函数声明形式创建的函数function 函数名(){},会在所有代码执行之前被创建(所以可以在函数被声明前调用)
* 使用函数表达式创建的函数var fun=function(){},不会被提前声明(所以不能在被声明前调用)
*/
/*
f1();//1
f2();//error
function f1() {//函数声明形式
alert(1);
}
var f2=function () {//函数表达式
alert(2);
}
*/
</script>
<!-- debug调试-->
<!-- this-->
<script>
/*
* 解析器在调用函数时每次都会向函数内部传递进一个隐含的参数:this
* this指向一个对象,称为函数执行的上下文对象
* 根据函数的调用方式不同,this会指向不同的对象:
* 以函数形式调用,this指向Window
* 以方法形式调用,this指向调用该方法的对象
* 以构造函数调用时,this就是新创建的那个对象
*/
function f() {
console.log(this);
}
f();//Window(以函数形式调用)
var obj={
name:"zhangsan",
sayName:f
}
console.log(obj.sayName);//f() {console.log(this);}
obj.sayName();//object(以方法形式调用)
</script>
<!-- 使用工厂方法创建对象-->
<script>
/*
* 工厂方法可以批量创建对象
* 使用工厂方法创建的对象都是Object类型,导致无法区分不同类型的对象→解决方法:构造函数
*/
function addInformation(name,age) {
var obj=new Object();
obj.name=name;
obj.age=age;
obj.sayName=function () {
console.log(this.name);
};
return obj;
}
var p1=addInformation("lisi",18);
p1.sayName();
var p2=addInformation("wangwu",18);
p2.sayName();
</script>
<!-- 构造函数-->
<script>
/*
* 构造函数创建方式与普通函数相同,但是首字母需要大写
* 普通函数直接调用,构造函数通过new调用
* 构造函数的执行流程:
* 1、调用(new)构造函数立刻创建一个新对象
* 2、将新建对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
* 3、逐行执行构造函数中的代码
* 4、将新建对象作为返回值返回
*
* 使用同一个构造函数创建的对象称为一类对象,也将一个构造函数称为一个类,通过构造函数创建的对象也称为该类的实例
*
* 使用对象都是Object的后代,(对象 instanceof Object)==true
*/
function Dog(name,age) {
this.name=name;
this.age=age;
//alert(this);//this就是新建的对象
}
var d=Dog();
var d2=new Dog();
console.log(d);//undefined
console.log(d2);//Dog
var d3=new Dog("wangcai",1);
console.log(d3);
/*
* instanceof:检查一个对象是否是一个类的实例
* 语法:对象名 instanceof 构造函数名
*/
console.log(d instanceof Dog);//true
console.log(d instanceof Object);//true
</script>