JavaScript
引入方法
1、body内嵌套:html结构加载完就会执行script
<body>
<script>
</script>
</body>
2、head 内文件引用: <script src=""></script>
3、head内直接嵌套:可能取不到下面元素
<head>
<script>
</script>
</head>
解决方法:window.onload
等页面中资源加载完才会执行
写多个window.onload时,后面的会覆盖前面的
<head>
<script>
window.onload = function(){
......
}
</script>
</head>
输入输出
输入
弹框提示输入:var 变量名 = prompt();
输出
1、控制台输出:console.log();
2、页面输出:document.write();
3、弹框输出:alert();
变量
var命令
JavaScript中的变量用var声明,是弱类型。变量名区分大小写,允许包含字母、数字、美元符号($)和下划线,但第一个字符不允许是数字,不允许包含空格和其他标点符号
数据类型
基本数据类型: number(数值型)、string(字符串)、boolean(布尔值)、null(空)、undefined(未定义)
引用数据类型: array(数组)、object(对象)
number
NaN属性 是代表非数字值的特殊值,该属性用于指示某个值不是数字。
Number.NaN是一个特殊值,说明某些算术运算(如求负数的平方根)的结果不是数字。
用 isNaN() 全局函数——判断一个值是否是 NaN 值。
string
1、string.length 返回字符串的长度
2、parseInt:字符串转整型
var str = "124.2345";
console.log( parseInt(str) );
//输出结果:124
3、parseFloat:字符串转浮点型
var str = "124.2345";
console.log( parseFloat(str) );
//输出结果:124.234
4、charAt():返回在指定位置的字符。
5、concat():连接两个或多个字符串。
6、indexOf():返回某个指定的字符串值在字符串中首次出现的位置,找不到返回-1
7、lastIndexOf():返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。
8、replace() :用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
9、slice():提取字符串的片断,并以新的字符串中返回被提取的部分。
10、split():把一个字符串分割成字符串数组。
11、substr(start,length):在字符串中抽取从 start 下标开始的指定数目的字符。
boolean
取值情况:
1、字符串:非空即为真
2、数值:非0即为真
3、undefined null:假
快速输出一个字符串变量的布尔值:
console.log(!!str);
null
表示一个“空”的值。
使用情况:
1、取不到id为div2元素的返回null
document.getElementById('div2');
2、object 表示为空对象
console.log( typeof null );
undefined
表示“未定义”
使用情况:
1、定义变量没有赋值
var a;
console.log(a);
console.log( typeof a);//undefined
2、函数没有返回值 默认返回undefined
function b(){
}
console.log( b() );
3、访问数组越界
4、访问对象没有的属性
5、判断函数参数是否传递
array
1、concat:连接两个或更多的数组,并返回结果。返回新的数组。
2、join:把数组的所有元素放入一个字符串,元素通过指定的分隔符进行分隔。 返回字符串。
解决字符串拼接:先将字符串转化为数组,然后调用join实现字符串拼接
arr.push(str);
return arr.join("");
3、pop:用于删除并返回数组的最后一个元素。 修改原数组。
4、shift:删除并返回数组的第一个元素。
5、push:方法可向数组的末尾添加一个或多个元素并返回新的长度。 修改原数组。
6、reverse:用于颠倒数组中元素的顺序,该方法会改变原来的数组。返回原数组。
7、slice:可从已有的数组中返回选定的元素。 返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
8、sort:用于对数组的元素进行排序。 数组在原数组上进行排序。
//从小到大排序
var a9 = [];
a8.sort(function(a,b){
return a-b;
})
//从大到小排序
var a10 = a8.sort(function(a,b){
return b-a;
})
9、splice:
splice(index,howmany,item,…) 向/从数组中添加/删除项目,然后返回被删除的项目。
该方法会改变原始数组。
index:必需;整数;规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany:必需;要删除的项目数量,如果设置为 0,则不会删除项目。
item:可选;向数组添加的新项目。
object
1、取对象的属性
可变的、动态的 属性———> [ ]
var person1 = {
name : "zs";
age :10;
}
var person2 = {
};
for(key in person1) //循环对象属性
{
console.log(key); //输出属性名
console.log(person1[key]); //输出属性值
person2[key] = person1[key];
}
写死的属性 —> .
2、克隆对象,返回一个新对象
var person1 = {
name : "zs",
age :10,
father:{
name:"zxx",
age:40
}
}
function clone (obj){
var result = {
};
for(var key in obj){
result[key] = obj[key];
}
return result;
}
var person3 = clone (person1);
person1.name = "lisi";
person1.father.name = "zyy";
console.log(person3);
//person3.name = "zs"
//person3.father.name = "zyy"
如果克隆的属性是对象——>深克隆
//递归调用clone函数进行深克隆
if(typeof obj[key] == "object"){
result[key] = clone (obj[key]);
}else{
result[key] = obj[key];
}
symbol(ES6增加的基本数据类型)
let name = Symbol();
obj[name] = ‘XX';
// 该属性不会出现在for...in、for...of循环中
判断类型——类型运算符
判断数据类型:typeof **
1、typeof “123” —— “string”
2、typeof 123 —— “number”
3、typeof true —— “boolean”
4、typeof undefined —— “undefined”
5、typeof {name:‘zs’} —— “object”
6、typeof null —— “object”
7、typeof [1, 2, 3] —— “object”
8、typeof 函数名 —— “function”
在使用 typeof 运算符时采用引用类型**存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”。
判断数组和对象
1、Array.isArray() —— 数组(true); 对象(false)
2、instanceof:
具体实例化对象 instanceof Array —— 数组(true); 对象(false)
具体实例化对象 instanceof Object —— 数组(false);对象(true)
3、具体实例化对象object.constructor 返回构造函数
变量提升
var 定义的变量会发生变量提升 :当前作用域的最上边声明变量但是没有赋值
console.log(a);
var a = 5; //报错 : undefined
//相当于:
var a;
console.log(a);
a=5;
var a = 5;
function fn(){
( var a; )
console.log(a);
var a = 10;
} //输出:undefined 变量提升
var a = 5;
function fn(){
console.log(a);
a = 10;
} //输出:5
var a = 5;
function fn(){
var a = 10;
console.log(a);
} //输出:10
比较语句
if-else
使用 if 来规定要执行的代码块,如果指定条件为 true
使用 else 来规定要执行的代码块,如果相同的条件为 false
使用 else if 来规定要测试的新条件,如果第一个条件为 false
var condition = false;
if (condition) {
alert("我不会出现!");
}
else {
alert("我会出现!");
}
switch-case
使用 switch 来规定多个被执行的备选代码块
var a = '3';
switch(a) {
case 4:
alert("4");
break;
case '3':
alert("3");
break;
case 2:
alert("2");
break;
case 1:
alert("1");
break;
default:
alert('错误。。。');
}
//执行结果:弹框显示3
循环语句
for:多次遍历代码块
for/in:遍历对象属性
while:当指定条件为 true 时循环一段代码块
do/while:当指定条件为 true 时循环一段代码块
while
while( num > 0 ){
console.log(num);
num--;
}
do-while
do{
console.log(num);
num--;
}while( num > 0);
运算符
赋值运算符
作用:把值赋给变量
赋值运算符 | 示例 | 等同表达 |
---|---|---|
= | x = y | x = y |
+= | x += y | x = x + y |
-= | x -= y | x = x - y |
*= | x * y | x = x * y |
/= | x /= y | x = x / y |
%= | x %= y | x = x % y |
算数运算符
+、++
1、+
应用:字符串拼接 、 数学运算
x = 7 + 8; //15
y = "7" + 8; //78
z = "Hello" + 7; //Hello7
2、++ (递加)
c++;
先参与运算 再++
++c;
先++ 再参与运算
-、–(递减)、*、/、%
能转成数值型——做运算 ;转不了输出NaN
比较运算符
比较运算符 | 描述 |
---|---|
== | 等于 |
=== | 等值等型 |
!= | 不相等 |
!== | 不等值或不等型 |
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
? : | 三目运算符 |
逻辑运算符
逻辑运算符 | 描述 |
---|---|
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非 |
类型运算符
类型运算符 | 描述 |
---|---|
typeof | 返回变量的类型 |
instanceof | 如果对象是对象类型的实例返回 true |
位运算符
位运算符处理 32 位数,该运算中的任何数值运算数都会被转换为 32 位的数,结果会被转换回 JavaScript 数
运算符 | 描述 | 例子 | 等同于 | 结果 | 十进制 |
---|---|---|---|---|---|
& | 与 | 5 & 1 | 0101 & 0001 | 0001 | 1 |
|| | 或 | 5 || 1 | 0101 || 0001 | 0101 | 5 |
~ | 非 | ~ 5 | ~0101 | 1010 | 10 |
^ | 异或 | 5 ^ 1 | 0101 ^ 0001 | 0100 | 4 |
<< | 零填充左位移 | 5 << 1 | 0101 << 1 | 1010 | 10 |
>> | 有符号右位移 | 5 >> 1 | 0101 >> 1 | 0010 | 2 |
>>> | 零填充右位移 | 5 >>> 1 | 0101 >>> 1 | 0010 | 2 |
上例使用 4 位无符号的例子。但是 JavaScript 使用 32 位有符号数。
因此,在 JavaScript 中,~ 5 不会返回 10,而是返回 -6。
~00000000000000000000000000000101 将返回 11111111111111111111111111111010
类
类:具有相同属性和方法的集合。
原型 prototype
构造函数有一个prototype属性,这个属性是一个指针,指向它的原型对象
原型对象下的属性和方法 可以被实例化对象所共享
原型下有一个constructor 属性指向它的构造函数
原型链 __ proto__
当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找,
如果prototype没有,就会去prototype关联的前辈prototype那里寻找,
如果再没有,则继续查找Prototype.Prototype引用的对象,以此类推,
直到Prototype. … .Prototype为undefined(Object的Prototype就是undefined),从而形成了原型链
继承
调用父类.call(this, ) 继承属性:
function Coder(name, age) {
Person.call(this, name, age);
}
继承父类的方法:
Coder.Prototype = new Person();
//需要手动把 Coder 的原型对象下的 constructor属性 指向Coder
Coder.prototype.constructor = Coder;
js继承机制:基于原型的继承机制
举个例子来说:假设有一个ClassA和ClassB,ClassB想继承ClassA
首先要在ClassA的构造函数里定义属性,在ClassA的原型里定义方法:
function ClassA() {
this.color = sColor;
}
ClassA.prototype.sayColor = function () {
alert(this.color);
};
然后在ClassB的构造函数中使用ClassA.call(this)来继承ClassA中的属性:
function ClassB() {
ClassA.call(this);
}
再用ClassB.prototype等于ClassA的一个实例对象来继承ClassA中的方法:
ClassB.prototype = new ClassA();
this 指向
改变this 指向的方法:call()、apply()、bind()
区别:
1、apply,call 是直接执行函数调用,bind是绑定,执行需要再次调用.
2、apply和call 的区别是apply接受数组作为参数,而call是接受逗号分隔的无限多个参数列表,call bind —> ,,,,;apply —> (this),[,,,,(其它参数)]
3、call(obj,1,2,3,) 从第二个参数开始有多个参数,用来代表函数的实参 apply(obj,[1,2,3]) 第二个参数是一个数组,数组中的每一个元素对应一个实参 bind(obj,1,2,3,)();
// this指向的几种情况:
function a() {
console.log(this);
}
a(); //Window
setTimeout(function(){
console.log(this);
},10); //Window
var aLi = document.getElementsByTagName('li');
for (var i = 0; i < aLi.length; i++) {
aLi[i].onclick = function(){
console.log(this);
}
} //<li>111</li> <li>222</li> <li>333</li>
for (var i = 0; i < aLi.length; i++) {
aLi[i].onclick = function(){
setTimeout(function(){
console