文章目录
JavaScript基础知识
用来表达传意最好的方式就是语言文字,所以用心阅读下面的文字,肯定可以得到收获:
字面量:
-
就是一些不可改变的值,比如数字1,2,3,4等;
-
字面量都是直接可以使用,但是我们一般不会直接使用字面量
变量:
- 变量可以用来保存字面量,而且变量的值可以任意改变;
- 变量更加方便我们使用,所以在开发中都是一个变量保存一个字面量,而从来不使用字面量
理解了上面两个定义,我们就能很好的去理解变量的含义:
//声明变量
var a;
//为变量赋值
a=3;
a=4;
//声明和赋值同时进行,两步变为一步
var a=3;
标识符
- 在js中所有的可以由我们自己命名的都可以称之为标识符
- 例如:变量名、函数名、属性名
- 命名规则:
- 标识符中可以含有字面、数字、下划线、$
- 标识符不能以数字开头
- 标识符不能是ES中关键字或者保留字
- 标识符一般采用驼峰命名法,如HelloWorld,字母首字母大写
数据类型:指字面量的类型
- 基本类型
- String
- 在js中字符串需要用引号引起来(单引号或者双引号,但是两者不可混用)
- var str=“我想:“去旅游”” 正确写法:转义 \ 或者 var str=“我想:‘去旅游’”
- Number
- JS中所有的数字都是Number类型
- 包括整数和浮点型,如果使用JS进行浮点型计算,可以得到一个不精确的结果
- var a=123; //数字123 var b=“123”//字符串123 使用typeof a 检查类型
- JS最大值: Number.MAX_VALUE Js最小值:Number.MIN_VALUE (大于0的最小正值)
- Number.MAX_VALUE *Number.MAX_VALUE 即Infinity 表示正无穷
- -Number.MAX_VALUE *Number.MAX_VALUE 即Infinity 表示负无穷
- var a=infinity a就是正无穷 类型Number
- NaN 表示Not a Number 不是一个数字
- Boolean
- 两个值true和false
- var bool=true
- Null
- 表示空,就一个值 即var a=null
- typeof 检查返回object
- Undefined
- 就一个值,表示未定义
- 当声明一个变量,并没有赋值,值就是undefined
- typeof检查返回undefined
- String
- 引用类型
- Object
强制类型转换
-
指将一个数据类型转换为其他的数据类型
-
类型转换主要指,将其他的数据类型转换为String、Number、Boolean
-
转换为Sting:
-
a.toString() ; 该方法不会影响原变量,返回值是String 所以可以将返回值付给一个变量以储存
-
注意:null和undefined没有toString()方法
-
调用String()函数 String(a); 强制类型转换
-
String(null) 返回值"null"
-
String(undefined) 返回值是"undefined"
-
- 转换为Number:
-
-
使用Number()函数
- 字符串转数字或者undefined转数字:NaN
- 数字字符串转数字:数字
- 字符串空格转数字:0
- 布尔ture转数字 :1,布尔false转数字:0
-
使用parseInt()
- 将字符串中有效的整数数字提取出来返回,转成数字
- 字符串要以数字开头,遇到小数点,小数点后面的内容不返回
- parseInt(a,10),a表示数字 10表示 10进制
-
使用parseFloat()
- 将字符串中有效的小数数字提取出来返回,转成数字
- 字符串要以数字开头,遇到小数点,小数点后面的内容不返回
-
-
转换为Boolean
- 使用Boolean()
-
运算符(操作符)
-
通过运算符可以对一个或者多个值进行运算,并获取运算结果
- typeof就是运算符,返回字符串类型
-
算数运算符
-
逻辑运算符
- !非
- &&与
- ||或者
-
赋值运算符
-
关系运算符
-
相等运算符
-
条件运算符
- 条件表达式?语句1:语句2
运算符优先级
- 自行查表
if…else…语句
let score=prompt("请输入成绩:")
alert(score)
if(score>10){
console.log("成绩>60")
}
else{
console.log("成绩<=60")
}
条件分支语句
let score=prompt("请输入成绩:")
switch(parseInt(score/10)){
case 9:
console.log("成绩优秀!");
break;
case 8:
console.log("成绩良!");
break;
case 7:
console.log("成绩合格!");
break;
case 6:
console.log("成绩合格!");
break;
default:
console.log("成绩不合格!");
break;
}
循环语句
- while语句
- 当n<5时,输出n,直到n不满足条件退出循环
- 先判断条件是否符合,再执行
let n=1;
while(n<5){
document.write(n+"<br/>")
n++;
}
结果:1,2,3,4
- do…while语句
- 当n<5时,输出n,不同的是do…while语句,即使不满足循环条件,也要至少执行一次,比如,n=6,也会执行一次do语句,直接返回6;
- 先执行语句,再判断条件是否允许
let n=1;
do{
document.write(n+"<br/>");
n++;
}while(n<5)
结果:1,2,3,4
let m=6;
do{
document.write(m+"<br/>");
m++;
}while(m==5)
结果:6
- for循环
for(let i=1;i<5;i++){
document.write(i);
}
结果:1,2,3,4
对象
- 使用new关键字调用的函数,是构造函数constructor
- 构造函数是专门用来创建对象的函数
- 使用typeof检查一个对象时,返回object
//创建对象
let obj=new Object();
console.log(obj);//返回{}
//添加属性
obj.name="lt";
obj.sex="男";
obj.age="18";
console.log(obj);//{name: "lt", sex: "男", age: "18"}
//读取属性
console.log(obj.name);//lt
//修改属性值
obj.name="修改";
console.log(obj.name);//修改
//删除属性
delete obj.name;
console.log(obj);//{sex: "男", age: "18"}
//特殊形式[]
obj["123"]=789;
console.log(obj["123"]);//789
//in 检查对象中是否有属性
console.log("name" in obj);//false
console.log("sex" in obj);//true
创建对象方式
- let obj =new Object();
- let obj ={}
引用类型和基本类型存储值对比
基本类型
- 基本类型存储形式为:栈
let value=9;//基本类型
变量 | 值 |
---|---|
value | 9 |
引用类型
- 引用类型存储形式为:
- obj和obj地址为栈
- obj地址指向的属性值,为堆5
let obj=new Object();//引用类型
obj.value=4;
变量 | 值 |
---|---|
obj | obj地址(指向value) |
value | 4 |
函数
- 函数就是一个对象
- 函数就是可以封装一些功能,在需要是可以执行调用
//创建函数 这种方式用的少
let fun = new Function(console.log("这是一个函数"));
fun();
//常用形式
function fun2(){
console.log("这是一个函数");
}
fun2();
//匿名函数赋值给变量
let fun3=function(){
console.log("这是一个函数");
}
fun3();
//箭头函数
let sum=(a,b)=>{
let s=0;
s=a+b;
return s;
}
console.log(sum(2,3));//5
//立即执行函数
(function(){
console.log("函数");
})();
枚举对象中的属性
let obj=new Object();
//添加属性
obj.name="lt";
obj.sex="男";
obj.age="18";
console.log(obj);//{name: "lt", sex: "男", age: "18"}
//枚举对象中的属性
for(let item in obj){
console.log(obj[item]);
}
使用工厂方法创建对象
- 缺点:使用工厂方法创建对象,使用构造函数都是Object,所创建的对象都是Object这个类型,导致我们无法区分出多种不同类型的对象
- 比如,以下两个对象,一个为person,一个为dog,但是类型都是Object,所以不便区分;
- 所以以构造函数的形式创建,专门用来创建Person对象和Dog对象,来区分类型;
function createPerson(name,age,gender){
//创建一个新对象
let obj=new Object();
//添加属性
obj.name=name;
obj.gender=gender;
obj.age=age;
obj.sayname=function(){
alert(this.name);
};
//将新的对象返回
return obj;
}
let per=createPerson(1,2,3);
per.sayname()
function createDog(name,age){
//创建一个新对象
let obj=new Object();
//添加属性
obj.name=name;
obj.age=age;
obj.sayname=function(){
alert('旺旺~~');
};
//将新的对象返回
return obj;
}
构造函数(和类相似)
- 创建一个构造函数 ,专门用来创建Person对象的
- 构造函数就是一个普通函数,创建方式和普通函数没有区别
- 不同的构造函数习惯上首字母大写
- 构造函数和普通函数的区别就是调用不同
- 普通函数直接调用;而构造函数需要使用new关键字来使用;
- 构造函数的执行流程
- 立刻创建一个新的对象;
- 讲新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象;
- 逐行执行函数中的代码;
- 将新建的对象作为返回值返回;
- 使用一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类;
- 我们将通过一个构造函数的对象,称为该类的实例;
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
this.sayname=function(){
return this.name;
}
}
let person1=new Person(1,2,3);
let person2=new Person(4,5,6);
let person3=new Person(7,8,9);
console.log(person1);//Person {name: 1, age: 2, gender: 3, sayname: ƒ}
console.log(person2);//Person {name: 4, age: 5, gender: 6, sayname: ƒ}
console.log(person3);//Person {name: 7, age: 8, gender: 9, sayname: ƒ}
console.log(person1.sayname());//1
console.log(person2.sayname());//4
console.log(person3.sayname());//7
this的情况总结
- 当以函数的形式调用时,this是window;
- 当以方法的形式调用时,谁调用方法this就是谁;
- 当以构造函数的形式调用时,this就是新创建的那个对象;
构造函数的修改
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
this.sayname=fun;
}
function fun(){
return this.name;
}
原型prototype
- 我们所创建的每一个函数,解析器都会想函数中添加一个属性prototype;
- 这个属性对应着一个对象,这个对象就是我们所谓的原型对象;
- 如果我们的函数作为普通函数调用,prototype没有任何作用
- 当函数通过构造函数调用时,他所创建的对象都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过_proto_来访问该属性;
- 原型对象就相当于一个公共的区域,所以同一个类的实例都可以访问到这个原型对象
- 我们可以将对象中公共的内容,统一设置到原型对象中;
- 当我们访问对象的一个属性或者方法时,他会先在对象自身中寻找,如果有就直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
- 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象具有这些属性和方法了;
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
Person.prototype.sayname=function fun(){
return this.name;
}
let person1=new Person(1,2,3);
let person2=new Person(4,5,6);
let person3=new Person(7,8,9);
console.log(person1.weight);//123
console.log(person2.weight);//123
console.log(person3.weight);//123
console.log(person1.sayname());//1
console.log(person2.sayname());//4
console.log(person3.sayname());//7
function myClass(){
}
//向myClass的原型中添加一个name属性
myClass.prototype.name="我是原型的属性name";
//实例化一个对象
let mc=new myClass();
//使用in检查对象中是否含有某个属性时,如果对象中没有,但是原型中有,也会返回true
console.log("name" in mc);//true
//可以使用对象的hasOwnProperty()来检查对象自身中是否有该属性
//使用该方法只有当对象自身含有属性时,才会返回true
console.log(mc.hasOwnProperty("name"));//false
//问题来了,hasOwnProperty从哪里来的呢?下面检查一下
console.log(mc.hasOwnProperty("hasOwnProperty"));//false 证明原型里也没有hasOwnProperty
//原型是对象,检查原型自身对象里有没有
console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));//false
//原型的原型也是对象,检查原型的原型对象里有没有
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true
总结:原型链
- 原型对象也是对象,所以他有原型,当我们使用一个对象的属性和方法时,会先在自身查找,
- 自身中如果有,则直接使用
- 如果没有则去原型对象中寻找,如果原型对象中有,则使用
- 如果没有则去原型的原型的寻找,直到找到Object对象的原型;
- Object的原型没有原型,如果Object中依然没有找到,则返回undefind
垃圾回收(GC)
- 就像人生活时间长了会产生垃圾一样,程序运行过程中也会产生垃圾
- 这些垃圾积攒过多以后,会导致程序运行的速度过慢
- 所以我们程序一个垃圾回收的机制,来处理程序运行过程中产生的垃圾
- 当一个对象没有任何的变量和属性对他进行引用,此时我们将永远无法操作该对象
- 此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,所以这种垃圾必须进行清理;
- 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁
- 我们不需要也不能进行垃圾回收的操作
- 我么需要做的只是将不再使用的对象设置为Null
数组
let arr=new Array();
arr=[1,2,3,4,5,6,7];
console.log(arr);//[1, 2, 3, 4, 5, 6, 7]
console.log(arr.length);//7
arr.length=5;//修改长度
console.log(arr);//[1, 2, 3, 4, 5]
arr[arr.length]=10;//向数组的最后添加数据