js代码用标签包裹起来,js代码可以放在行内,body的后面,或者body之前,外部,但是通常我们会将js代码放在title的标签之下,但是如果这样的话,浏览器会先加载js代码,而不会先加载html的部分。由此,我们可以用window.onload = function(){js..代码}这种写法,但请不要忘记script标签。
attributes 属性
该属性是获取标签中的属性,列如class,id,和href之类的属性,如果一个标签中包含多个属性则使用attributes[num]获取的是第几个属性。该属性还可以有length和value属性。
cookie属性
是浏览器存储信息的东西document.cookie().
一、面向对象
面向对象的三大特性:继承,封装,多态。现在我要求我们要创建3个对象,但是我们看到是不是都有shoool属性,而且这些个属性还不带变的,所以我们由此引出来原型的概念。
let xx = { |
二、JS原型
首先我们看一个例子:
function Person(age,name){ |
为什么会是false呢?不都是构造函数中的方法嘛,因为实例化对象不同,所以调用的方法也不同,有一百个对象,那么就要调用一百次这个方法,那么这不浪费内存空间嘛,由此引出————原型(prototype)函数都有原型,不是只有构造函数才有原型。
续—
// 说明如果这个对象中没有这个属性,那么就去它的原型中去寻找 |
原型的作用:数据共享,节省内存空间。
function Person(age,name){ |
原型分为显示原型(prototype)和隐式原型(proto),每一个函数都会有一个显示原型,每一个实例对象都有一个隐式原型,实例对象的隐式原型和函数的显示原型相等
function Person(name,age){ |
原型链(最终结果:Object.Prototype)
首先我们实例化对象的时候,如果构造函数中没有对应的方法或者属性,那么我们就要到原型中去寻找。如过没有找到,就会报错,如果在构造函数中找到,则输出相应的结果。自身=>构造函数中的原型=>原型中构造函数中的原型
function Person(){ |
作用域链的作用域
function fn (callback) { |
原型继承: 利用原型,可以实现继承
function Animals () { |
简单的原型继承
var parent = {name : 'zs',age : 16}; |
利用简单的原型继承可以实现非常简单的原型继承,可以不用构造函数。因为每次要 写一次构造函数都会很麻烦。
三、JS dom 操作
众说周知JS其实可以分为两个大块,dom和bom部分,今天我们就来说说dom部分。document代表的是整个文档。
1. dom选择器
- document.getElementById();//在开发过程中我们并不太常使用这种方法来获取id属性
- document.getElementsByClassName()[]//类数组获取样式
- document.getElementsByTagName()[]//获取标签名类似一个数组,但不是一个数组,简单来说是类数组
- document.getElementByName()获取某些具有name属性的标签
- document.querySelectorAll()获取css选择器,有缺点,包括ie7和一下都没有
- document.querySelector()css选择器,同上。
2. dom节点类型
parentNode->父节点(body->html->document->null)
childNodes->子节点们
javascript<div>
<section></section>
<span></span>
<p></p>
</div>
<script>
window.onload = function(){
var odiv = document.getElementsByTagName("div")[0];
console.log(odiv.childNodes.length);
}
</script>
//猜猜结果是什么? 是7为什么呢?因为里面包含了文本节点,不可能是3的哟。lastChild->最后一个子节点
fristChild->第一个子节点(这两个取决你是否换行,如果有则是文本节点)
nextSibling->后一个兄弟节点
previousSibling->前一个兄弟节点
3. 基于元素节点树的遍历
parentElement->父元素节点
children->当前元素子节点
fristElement->第一个元素节点
lastElement->最后一个元素节点(IE不兼容同上)
nextElementSibling/preElementSibling->后一个/前一个兄弟节点
4. 节点的四个属性
- nodeName->元素的标签名
- nodeValue->text节点或Comment节点的文本内容,可读写
- nodeType 该节点的类型
- 元素节点——-1
- 属性节点——–2
- 文本节点———–3
- 注释节点————-8
- document———-9
- DocumentFragment—-11
- Attributes 该节点的属性集合
5. 节点的增删改查
- 创建节点———–>createElement(“节点名称”);
- 创建文本节点————>createTextNode(“节点名称”)
- 删除节点—————> removeChild(“节点名称”);
- 增加节点—————->appendChild(“节点名称”)往后追加节点
- insertBefore(节点1,节点2) //追加节点2 在节点1的前面
- insertAfter()同上。
四、JS 正则部分
js中的正则又很多种方法不过常用的还是
test(),search() ,repleace() act..
1. 正则表达式模式
^ | //g | {4,11} | /d | /w | (任意值/) |
---|---|---|---|---|---|
开始符号 | 类是与全局 | 最少是4次,最多为11次数字相当于区间 | 全为数字 | 全为字母,数字,下划线 | 任意一个值 |
$ | [1-9] | {4,}最少为4次 | /D | /W | n+,n*,n? |
结束符号 | 出现1-9中的任何一个数字 | {,11}最多为11次 | 非数字 | 非数字,字母,数字,下划线 | (至少一个)(至少0个或多个)(0个或多个) |
2. 使用RegExp对象
在 JavaScript 中,RegExp 对象是一个预定义了属性和方法的正则表达式对象。
使用 test()
test() 方法是一个正则表达式方法。
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。
以下实例用于搜索字符串中的字符 “e”:
两种定义方式,如果不引入变量则使用最多的还是第一种方式,如果字符串中包含\则需要使用转义字符/\即可~
var patt = /e/g; |
3. 举个例子(验证QQ号)
<script> |
五、target事件机制
有这么一个问题,有很多的li我需要点击某个li标签,来打印对应的li值。恩,这我们该怎么做?
首先我们先想到的就是就是获取的ul的id,然后获取所有的li,遍历每一个li,给li注册点击事件。弹出值。
但是在这里我们不能使用var来定义变量,我们需要使用let。这也是一种方法。但是我们可以使用target
<body> |
这里我们无需为li注册点击事件,如果我们li没有点击事件的话,我们就是向上一层寻找事件,上一层再没有再找,这就是事件冒泡。target 属性规定哪个 DOM 元素触发了该事件。这个 event 参数来自事件绑定函数。而这个e就相当于我们点击了哪一个li。
六、作用域和内存问题
ECMAScript变量包含两种不同的数据类型的值,基本数据类型和引用数据类型,基本数据类型:String、Blooean
Number 、null 、 undefined,引用类型包括:Object、Symbol。应用类型的值是保存在内存中的对象,对其引用类型的值我们可以添加属性和方法,也可以删除属性和方法。但是我们的基本数据类型的值则是不行。
传递参数
函数中的参数都是按照值传递的,不像变量有按值和按引用传递,而参数只能按照值传递。
对象也是按值传递的,当在函数内部重写obj,这个变量引用的就是一个局部对象,函数执行完就会立即被销毁。
function setName(obj){ |
对象
对象赋值时地址赋值,两个对象指向的时同一内存空间,所以当我们改变其中的一个对象的时候,另外一个也会发生改变
var obj = { |
var a = { |
以上的age的值依然为14,这是一开始,a 和obj都指向同一内存空间。但是这个时候改变了obj的指向。但是不会影响a所以a还是原始的指向
var a = 3; |
作用域链
function a(){ |
上面的代码解释了内层函数(站在其他函数上面看世界)是为什么访问到外层函数的变量,每一个函数在执行的前一刻都会产生一个执行期上下文(AO)。作用域链一层一层的往上面查找。
函数执行完会立即销毁作用域,则再次调用该函数会另外产生一个内存空间,但是若是函数中有函数被返回出去,则这个空间不会被销毁。
七、函数
函数的三种方式
- 函数表达式
- 函数声明
- 构造函数
//第一种 |
回调函数
回调函数是一个作为变量传递给另外一个函数的函数,它在主体函数执行完之后执行。
八、预编译
imply global暗示全局变量,一切未经声明的变量都为全局变量归window所有
a = 3 //window.a |
在全局中声明的变量归window所有
var a = 123 // window.a 123 |
预编译发生在函数执行的前一刻
大多数可以用一句话概括,变量声明提升,函数整体提升。在JavaScript中函数执行的时候都会发生预编译。
可以划分为四个步骤:
- 生成AO(Active Object)对象(执行期上下文)
- 找出形参和变量的声明,将形参和变量声明作为AO的属性,并且值为undefined。
- 将实参值和形参的值统一。
- 找出函数声明,值赋予函数体
function fn(a) { |
//第一步创建AO对象和赋值undefined |
预编译不止发生在函数中,也同时发生在全局,也会生成一个对象GO(global Object)只不过没有将实参和形参相统一。其余步骤一样,先创建GO,再创建AO。
九、this
- 全局作用域中,this指向Window
console.log(this)---------Window |
- 函数没有实例对象,函数预编译,this指向Window
function fn1 () { |
- 函数内部的this,是由谁调用了函数来决定的。
function Fn2 () { |
- 对象中的this是指向这个对象。
var obj = { |
- 利用call改变this的指向,第一个参数是this的指向,第二个是参数
function fn4 (name) { |
十、隐式转换
在JavaScript中+和-号可以是运算符的连接,但是如果两边是字符串的话会有什么作用呢?
console.log("22"-"11"+"12")//1112 |
如果加号的两边或者一边是字符串则转换成string进行字符串拼接。但是如果是-号,则优先转换成number
十一、包装类对象和类型检测
(1)基础数据类型和引用类型,基础类型是不可以调用方法和添加属性的
var str = "hello" |
这里的t还有长度都是临时的对象,并不是真正的属性和方法。
(2)一般的类型检测会使用typeof 和 intanceof
- typeof(确定,无法确定null类型,无法确定对象是属于一类的)
- 测试类型 intanceof 判断是否为哪一种类型
console.log(typeof [1,3]) ---object |
(3) 除去number、string、null、undefined、Boolea这五种是属于基本数据类型,其余的为引用类型(又称复杂类型)如果我们构造函数中返回值类型不是基本数据类型,则不是我们创建的实例
function Person(){ |
十二、严格模式
严格模式是 一种特殊的运行模式,它修复了部分语言的不足,更加增强了错误检查,并增强了安全性。
使用严格模式:”use strict”一些浏览器不知此严格模式的情况下,只会解析成字符串,所以不会有错误。
严格模式下不允许:
- 不允许使用with
- 不允许对象属性有相同的命名
- 不允许使用delete运算符
- 不允许eval,arguments变为关键字,不能作为变量名、函数名
- 禁止八进制的字面量
- eval成为独立的作用域
通过object.create(参数)创建一个空对象,这个对象原型指向该参数