Js
简介
三部分组成
- ECMAScript
- DOM
- BOM
特点
-
解释型语言
- 不用编译,直接执行
- 运行速度慢
- js使用JIT技术优化,速度变快
-
动态语言
-
基于原型的面向对象
-
类似C和Java的语法
基本语法
编写位置
-
客户端JS,在浏览器中运行
-
编写到
hello world
- 创建html文件
- 在html文件的head标签中创建一个script标签
严格区分大小写
- 和C语言一样
注释和C语言一样
标识符
- 第一个字符必须是字母、下划线或者美元符号($)
- 其他字符可以是字母、下划线、美元符号或者数字
- 惯例标识符采用驼峰命名法
关键字和保留字
- 关键字 break、else、new、var、 case、 finally 、 return、 void 、 catch 、for 、switch 、 while 、 continue、 function 、this 、 with 、default 、 if 、 throw 、 delete 、 in 、 try 、do 、 instranceof、 typeof
- 保留字abstract 、 enum 、int 、 short 、 boolean 、export 、interface、 static、 byte 、extends 、 long 、 super 、 char 、 final 、native 、synchronized 、 class 、float 、 package 、throws 、 const 、goto 、private 、transient 、 debugger 、 implements 、protected 、 volatile 、 double 、import 、public
数据类型
-
字符串String
-
使用单引号或双引号扩起来
-
数值转字符串
- toString()
- String()
-
-
数值型Number
- NaN数值计算没有结果返回,not a NUmber
- 非数值转换为数值Number().pareInt() parseFloat()
-
布尔Bool
-
null型Null
-
undefined型Undefined
- 声明但是没有初始化,这个变量就是undefined
-
其他的类型都成为Object(对象)
运算符
-
算数运算符
- 和C差不多
-
位运算符
- 和C差不多
-
关系运算符
- 和C差不多
流程控制
-
if。。。else
- if(expression)
statement - if(expression)
statement
else
statement
- if(expression)
-
switch …case
- switch(语句)
{
case 表达式1:
语句;
。。。。。。
default:
语句;
}
- switch(语句)
-
while、for
- C一样
-
break continue
对象
创建对象两种方式
- var perspon = new Object();
person.name = “孙悟空”;
person.age = 17; - var person = {
name:“孙悟空”,
age:17
};
对象属性访问两种方式
- person.age
- person[‘age’]
引用数据类型
- 对象的值是保存在内存中
- 变量的属性是对象时,其实是变量对对象的引用
栈 和堆
- 栈保存基本变量
- 堆保存对象
数组
-
是对象的一种
-
创建数组 var array = [1,2,3]
-
数组可以保存任意类型的数据
- var arr = [123, ‘hello’, false]
函数
-
函数的声明
- 函数也是一个对象,函数也是在堆中保存
- 声明需要用function关键字
var sum = function(a, b) {return a+b}; - 第二中方式
function sum(a, b)
{
return a+b;
}
-
函数的调用
- 直接传参
- 都是值传递
-
执行环境
- 执行环境定义了变量或函数有权访问其他数据
- 每个执行环境后有一个与之关联的变量对象, 环境中定义的所有变量和函数都保存在这个对象中
- web浏览器中的全局执行环境是window对象。
- 内部环境可以读取外部环境的变量,反之则不行
-
函数内部属性
-
arguments
- 该对象是一个数组,保存函数的参数
- 该对象有一个属性callee表示当前函数
-
this
-
引用的是一个对象
-
在外层代码中,this引用全局对象
-
在函数内部
-
构造函数
- 所生成的对象
-
调用对象的方法
- 当前对象
-
apply或者call调用
- 参数指定的对象
-
其他方式
- 全局对象window
-
-
-
-
构造函数
- 和C++差不多
- 使用new来调用
-
new关键字
- 构造函数总是由new关键字调用
- 构造函数首字母大写
-
属性访问
- 访问和修改类似
- 删除属性 delete 对象.属性名
- constructor 每个对象都有一个constructor属性,它引用了当前对象的构造函数
-
垃圾回收
- 类似java
- 不要自己管理内存
-
原型继承
-
构造函数中存在着一个 prototype对象
-
这个对象保存一些属性,通过该构造函数创建的对象都可以访问存在原型中的属性
-
创建原型
- 构造函数.prototype
- 可以增删改创建原型对象中的属性
-
prototype属性,只存在于函数对象中,其他对象没有这个
-
大多数对象都有原型
-
-
instanceof
-
使用它来检查对象类型
-
var result = 变量 instanceof 类型
- ???
-
-
call() 和apply()
-
都可以指定一个函数的运行环境对象
-
使用方式
- -函数对象.call(this对象,参数数组)
- -函数对象.apply(this对象, 参数1,参数2)
-
-
闭包
- 这是js自身作用域结构,
- 作用是:相关局部变量在函数调用结束之后将继续存在
Math对象
- 子主题 1
DOM
是什么
- Document Object Model 文档对象模型
- Js通过DOM操作html
- 文档表示html网页
- 对象表示将网页中的每一个部分转化为一个对象
- 使用模型来表示对象间的关系
模型,树形的模型
-
html
-
head
-
title
- 文本节点
-
-
body
-
a
- 文本节点
-
-
节点
-
网页的最基本组成 部分Node
-
html标签、属性、文本、注释、整个文档都算是一个节点
-
分类
-
文档节点:整个html文档
- document对象名作为window对象的属性可以直接使用
-
元素节点:html文档中的html标签
- 使用document的方法来获取节点
-
- document.getElementById()
-
- document.getElementsByTagName()
-
- document.getElementsByName()
-
属性节点:元素中的属性
-
元素节点.getAttributeNode(“属性名”);
-
其他属性
-
• nodeValue
- – 文本节点可以通过nodeValue属性获取和设置文本节点的内容
-
• innerHTML
- – 元素节点通过该属性获取和设置标签内部的html代码
-
-
-
文本节点:html标签中的文本内容
- 通过元素节点获取文本节点
- 元素节点的第一个子节点一般为文本节点
-
- 元素节点.firstChild;
-
-
获取元素节点
- 通过document对象调用
-
- getElementById()
- – 通过id属性获取一个元素节点对象
-
- getElementsByTagName()
- – 通过标签名获取一组元素节点对象
-
- getElementsByName()
- – 通过name属性获取一组元素节点对象
-
获取元素节点的子节点
- 通过具体的元素节点调用
-
- getElementsByTagName()
- – 方法,返回当前节点的指定标签名后代节点
-
- childNodes
- – 属性,表示当前节点的所有子节点
-
- firstChild
- – 属性,表示当前节点的第一个子节点
-
- lastChild
- – 属性,表示当前节点的最后一个子节点
-
获取父节点和兄弟节点
- 通过具体的节点调用
-
- parentNode
- – 属性,表示当前节点的父节点
-
- previousSibling
- – 属性,表示当前节点的前一个兄弟节点
-
- nextSibling
- – 属性,表示当前节点的后一个兄弟节点
-
节点的修改
- • 创建节点– document.createElement(标签名)
- • 删除节点– 父节点.removeChild(子节点)
- • 替换节点– 父节点.replaceChild(新节点 , 旧节点)
- • 插入节点– 父节点.appendChild(子节点)
- – 父节点.insertBefore(新节点 , 旧节点)
事件
- JS与html交互是通过时间实现
- 事件例子:点击某个元素,键盘按键。。。
* 全局作用域
* 函数作用域
* 没有块作用域(ES6有了)
- 作用
* 隔离变量,不同作用域下同名变量不会有冲突
-
作用域与执行上下文
- 区别1
-
全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数调用时
-
全局执行上下文环境是在全局作用域确定之后, js代码马上执行之前创建
-
函数执行上下文环境是在调用函数时, 函数体代码执行之前创建
- 区别2
-
作用域是静态的, 只要函数定义好了就一直存在, 且不会再变化
-
上下文环境是动态的, 调用函数时创建, 函数调用结束时上下文环境就会被释放
- 联系
-
上下文环境(对象)是从属于所在的作用域
-
全局上下文环境==>全局作用域
-
函数上下文环境==>对应的函数使用域
-
作用域链
- 理解
-
多个上下级关系的作用域形成的链, 它的方向是从下向上的(从内到外)
-
查找变量时就是沿着作用域链来查找的
- 查找一个变量的查找规则
-
在当前作用域下的执行上下文中查找对应的属性, 如果有直接返回, 否则进入2
-
在上一级作用域的执行上下文中查找对应的属性, 如果有直接返回, 否则进入3
-
再次执行2的相同操作, 直到全局作用域, 如果还找不到就抛出找不到的异常
var a = 2;
function fn1() { var b = 3; function fn2() { var c = 4; console.log(c); console.log(b); console.log(a); console.log(d); } fn2(); } fn1();
-
面试题
-
面试题1
var x = 10;
function fn() {
console.log(x);
}
function show(f) {
var x = 20; f();
}
show(fn);
-
面试题2
var fn = function () {
console.log(fn)
}
fn()
var obj = {
fn2: function () { console.log(fn2) }
}
obj.fn2()
-
闭包
-
引子实例
<meta charset="UTF-8"> <title>Title</title> <script type="text/javascript"> /*
需求: 点击某个按钮, 提示"点击的是第n个按钮"
*/ </script>
<button>测试1</button> <button>测试2</button> <button>测试3</button>
-
理解闭包
- 如何产生闭包?
- 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包
- 闭包到底是什么?
-
使用chrome调试查看
-
理解一: 闭包是嵌套的内部函数(绝大部分人)
-
理解二: 包含被引用变量(函数)的对象(极少数人)
-
注意: 闭包存在于嵌套的内部函数中
- 产生闭包的条件?
-
函数嵌套
-
内部函数引用了外部函数的数据(变量/函数)
-
常见的闭包
-
将函数作为另一个函数的返回值
-
将函数作为实参传递给另一个函数调用
-
-
闭包的作用
-
使用函数内部的变量在函数执行完后, 仍然存活在内存中(延长了局部变量的生命周期)
-
让函数外部可以操作(读写)到函数内部的数据(变量/函数)
问题:
-
函数执行完后, 函数内部声明的局部变量是否还存在?
-
在函数外部能直接访问函数内部的局部变量吗?
-
-
闭包的生命周期
-
产生: 在嵌套内部函数定义执行完时就产生了(不是在调用)
-
死亡: 在嵌套的内部函数成为垃圾对象时
-
-
闭包的应用: 自定义JS模块
闭包的应用 : 定义JS模块
-
具有特定功能的js文件
-
将所有的数据和功能都封装在一个函数内部(私有的)
-
只向外暴露一个包信n个方法的对象或函数
-
模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能
-
-
闭包的缺点及解决
- 缺点
-
函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长
-
容易造成内存泄露
- 解决
-
能不用闭包就不用
-
及时释放
-
面试题
- 面试题一 //代码片段一 var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //? //代码片段二 var name2 = "The Window"; var object2 = { name2 : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name2; }; } }; alert(object2.getNameFunc()()); //?
-
面试题二
function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,n); } }; } var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,? var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,? var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
-