目录
JavaScript是什么?
是一种脚本语言,直接被浏览器执行,不需要被编译,可以插入在HTML中的编程代码(<body>和<head>中),实现与用户实时交互,可以用来创建动态更新内容,例如:前端验证
为什么要用JavaScript?
增强了与用户的互动性,及时性,并减少了服务器的压力,例如:一些基本验证由用户端进行
JavaScript组成:
- ECMAScript:核心部分,定义js的语法规范
- DOM:Doucument Object Model(文档对象模型)主要是用来管理页面
- BOM:Browser Object Model(浏览器对象模型):控制页面的前进,后退,页面刷新,地址栏,历史记录,屏幕宽高
ECMAScript
基本语法:
- 每个语句以;结束
- 语句块用{...}
- 区分大小写
- 变量弱类型 var i=true
- 写在script标签中
- 可引用已定义好的JavaScript(内部和外部都可以)
- 字面量:是一个常量
- 变量:用于存储数据值/字面量
数据类型:
指的是字面量的类型
基本类型:
String(function),Number(function),Boolean(function),Null(Object),Undefined
String:单引号和双引号不能交叉使用
Number:不区分整数和浮点数
Boolean:true和false
Null:空对象指针
Undefined:使用var声明变量但未初始化,区分空对象指针与尚未定义的变量
引用类型:
Object,function,Array(function)
Object:
- 一组数据或功能的集合,键值对无序集合
- JavaScript对象是动态类型,可自由添加或删除属性
function:
需要在某个事件发生时执行代码可以写在函数内,函数可以重复引用,无序的特别对象,当赋值给对象中的一个属性就成为了该对象的方法
没有函数重载
数组:
有序的特别对象,与对象不同的是使用数字来作为索引操作元素
他们三者之间的关系:数组和对象都可以构造函数(函数包涵构造函数)生成,都形似键值对,一个通过字符串来找,一个通过索引来找,函数相当于在对象的基础之上,加上了可执行的代码,函数赋值给对象的属性变成了方法
变量:
声明:
var 变量名
先声明,后读写,先赋值,后运算
变量类型:
值类型:
- 占用空间固定,保存在栈中
- 保存和复制的是值本身
- 使用typeof检测数据的类型
- 基本类型数据是值类型
引用类型:
- 占用空间不固定,保存在堆中
- 保存于复制的是指向对象的一个指针
- 使用instanceof检测数据的类型
- 使用new()方法构造出的对象是引用类型
作用域:
在js中只有函数可以限定变量的作用域,不同函数内部的同名变量互相独立,互不影响
全局作用域
- 直接编写在script标签中的JS代码,都在全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建,我们可以直接使用
- 在全局作用域中,创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问的到
函数作用域
- 调用函数时创建函数作用域,函数执行完毕后,函数作用域销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
- 在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量
- 当在函数作用域操作一个变量时,他会先在自身作用域中寻找,如果有就直接使用,如果没有则向上一级作用域中寻找,知道找到全局作用域,人如果全局作用域中依然没有找到,则会报错ReferenceErrror
- 在函数中,不使用var声明的变量都会变成全局变量,相当于window.变量=100;
- 定义形参就相当于在函数作用域中声明了变量
全局变量:
- 在函数体外定义的变量,在函数体内部定义的无var的变量
- 可以在任何位置调用
- 全局变量是全局对象的属性
局部变量:
- 在函数内部使用var声明的变量和函数的参数变量
- 在当前函数体内部调用
- 局部变量是调用对象的属性
作用域链:
- 内层函数可访问外层函数局部变量,外层函数不能访问内层函数局部变量
- 一般情况,变量取值到创建这个变量的函数的作用域中取值,但是如果在当前作用域中没有查到值,就会向上级作用域去查(或被调用那一层查)直到查到全局作用域,这一过程就叫做作用域链
变量提升
使用var关键字声明的变量,会在函数中所有的代码执行之前被声明,但是如果声明变量时不使用var关键字,则变量不会被声明提前,函数声明形式创建函数也会在函数中所有代码执行之前执行,和上面的一样,生命周期不一样
构造函数
- 构造函数就是普通的函数
- 开头字母要大写
- js没有类,直接使用构造函数创建对象
- 调用的时候直接使用new就可以将其作为对象使用
构造函数执行流程
- 立刻创建一个新的对象
- 将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象,并为其赋值
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
为什么要有构造函数?
- 区分对象,不能只是object,如果只用函数,就都是 object对象的,导致我们无法区分出多种不同类型的对象
- 普通函数没有返回值调用为undefined
- 构造函数没有返回值调用为object,如果有返回值,则是当前对象,不是Object
构造函数的方法
第一种方法:创建2个需要创建两个sayName方法,创建100个需要创建100个sayName方法
第二种方法:将sayName方法在全局作用域定义,就可以使所有对象共享同一个方法,空间和运行效率都有很大的提高
//第一种
function Person(name,age){
this.name=name;
this.age=age;
this.sayName=fun;
}
function fun(){
alter("大家好,我是"+this.name);
};
var per=new Person("子轩",18);
var per2=new Person("玄门",20);
缺点:
将函数定义在全局作用域,污染了全局作用域的命名空间,而且定义在全局作用域中也很不安全
解决方案:
原型对象:
为所有同一类创建的实例开辟一个公共空间,提供使用,就会解决以上的问题(污染和性能方面的问题)
参数和返回值
函数的参数
调用函数时解析器不会检查实参的类型(有参数的时候),也不会检查实参的数量,多余的实参不会被赋值,如果实参的数量少,则没有对应参数的形参将是undefined
函数的实参可以是任意的数据类型
实参
可以是任意的数据类型,也可以是一个对象,当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递
参数可以是一个对象,也可以是一个函数
hanshu()--调用函数,相当于使用的是函数的返回值
hanshu---函数对象,相当于直接使用函数对象,里面的代码
fun(hanshu())和fun(hanshu)
函数的返回值
return后的值将会作为函数的执行结果返回,可以定义一个变量,来接受该结果
return后面的语句就不执行了
retun语句后面不跟让任何值就相当于返回一个undefined,如果函数中不写return,则会返回undefined
return后可以跟任意类型的值
this和arguments
在调用函数时,浏览器每次都会传递进两个隐含的参数
1.函数的上下文对象this
解析器在调用函数每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this,this指向的是一个对象,这个对象我们称为函数执行的上下文对象
根据函数的调用方式的不同,this会指向不同的对象
- 以函数的形式(相当于window的方法)调用时,this永远都是window
- 以方法的形式调用时,this就是调用方法的那个对象
- 当以构造函数的形式调用时,this就是新创建的那个对象
2.封装实参的对象 arguments
- arrguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度,在调用函数时,我们所传递的参数都会在arguments保存,arguments.length可以用来获取实参的长度
- 我们即使不定义形参,也可以通过argumens来使用实参,只不过比较麻烦,arguments[0]表示第一个是实参
- arguments.callee:这个属性对应一个函数对象,就是当前正在执行的函数的对象(函数的代码)
- 它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。利用
arguments
,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值
包装类
在JS中为我们提供了三个包装类,通过这三个包装类额可以将基本数据类型的数据转换为对象
String()---可以将基本数据类型字符串转换为String对象
Number()---可以将基本数据类型的数字转换为Number对象
Boolean()---可以将基本数据类型的布尔值转换为Boolean对象
方法和属性能添加给对象,不能添加给基本数据类型
当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转化为对象,然后在调用对象的属性和方法,调用完以后,在将其转化为基本数据类型
var s=123;
s=s.toString(); //"123",临时转换,调用完之后,在转换回去
s.hello="你好"; //undefined
console.log(s.hello);
正则表达式:
用于定义一些字符串的规则,计算机可以根据正则表达式,来检查一个字符串是否符合规则,获取将字符串中符合规则的内容提取出来
正则表达式是一个对象,严格区分大小写,但是可以设置为忽略大小写
Dom(document Object Model)
js中通过dom来对HTML文档进行操作
文档:文档表示的就是整个HTML网页文档
对象:对象表示将网页中的每一部分都转换为了一个对象
模型:使用模型来表示对象之间的关系,这样方便我们获取对象(对象多了之后不好管,有了关系就好管理了)
通过可编程的对象模型,JavaScript 获得了足够的能力来创建动态的 HTML。
- JavaScript 能够改变页面中的所有 HTML 元素
- JavaScript 能够改变页面中的所有 HTML 属性
- JavaScript 能够改变页面中的所有 CSS 样式
- JavaScript 能够对页面中的所有事件做出反应
Bom(浏览器对象模型)
浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器"对话"。
Window 对象是BOM中所有对象的核心,除了是BOM中所有对象的父对象外,还包含一些窗口控制函数。
文档的加载
浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行,如果将script标签写到页面的上边,在代码执行时,页面还没有加载,页面没有加载DOM对象也没有加载,会导致无法获取到DOM对象,就无法触发到js中的事件,如何解决?(一般来说需要将js代码写道触发事件按钮的下面,才能够正常的触发,但是就是向写在head里面,不想写在body里面,怎么办?1.可以写道页面的下部,为了可以在页面加载完毕以后在执行js代码,这样太麻烦)
2.onload事件会在整个页面加载完成之后触发,为window绑定一个onload事件,该事件对应的相应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了