js的简单介绍以及入门
-
学习方式
在linux环境下,使用vi编辑器
执行环境:nodejs -
js介绍
js在浏览器中运行,进行表单验证,页面的布局更新(dom)操作,浏览器的操作(bom)。
js解释器,IE,网景推出自己的浏览器,浏览器中有JS解释器,由于js解释器的不统一,js标准就不统一,就产生了兼容性问题js是解释型语言,不需要编译,直接运行在解释器上
对比java/c这类编译型, java->.class 在运行到jvm上,c->.out 再运行到linux上js的标准 ECMAScript5
规定了语法:变量、关键字、保留字、表达式、流程控制语句、对象、函数、数组…DOM : Document Object Model 文档对象模型, 浏览器厂商通过es5编写的控制html/css的代码
document.getElementById(); dom.addEventListener() dom.attachEvent()
BOM : Browser Object Model 浏览器对象模型,浏览器厂商通过es5编写的控制浏览器的代码
alert(); setTimeout(function(){ },1000) XMLHttpRequest (ajax)
android/ios
移动互联,前端发展,android+h5+js
nodejs,google开发,将浏览器中的js解释器掏出来,可以安装在任意服务器端,并且提供了大量的基础库,file、http,这个时候js具备服务器端能力
在nodejs中,不存在兼容性问题,因为nodejs中不存在BOM,DOM操作,因此切记不要在nodejs中执行BOM、DOM代码,由于
不存在兼容性问题,nodejs是可以大量发挥js高级标准,ES6语法一般在nodejs中可以完全运行 -
hello world
在nodejs中,通过vi编辑器
console.log("hello world");
- 注释
// (单行注释)
/**/ (多行注释) - 变量
1.js是弱类型语言
变量的数据类型在初始化的时候也不确定
变量的数据类型可以随时改变
变量的数据类型细分不明显
2.var, let, const
var在es5标准下用于声明一切对象
1. 变量可以重复声明
var a = 3;
var a = "hello world"
- 变量声明会被提升 (函数的声明也会)
console.log(a);
var a = 3;
3. var声明的变量没有局部作用域
function foo(){
if(true){
var a = 3;
console.log("inner",a);
}
console.log("outer",a);
}
foo();
es6中新增了let,和const
let 类似于java中的变量声明,数据类型确定不能发生改变
const 声明一个常量,要进行初始化,声明以后不可以发生改变
-
数据类型
1> 分类-
五种基本数据类型
变量的值是保存在栈区Number
var a = 2;
var a = 2.1;
var a = 0X10;
var a = 010;
String
var a = “hello world”
var a = ‘hello world’
var a =<ul> <li>terry</li> <li>larry</li> <li>tom</li> </ul>
;
Boolean
var a = true;
var a = false;
Null
var a = null;
Undefined
var a;
var a = undefined; -
引用数据类型(指针)
变量的引用地址保存在栈区,真正的值保存在堆区
除了基本数据类型之外的所有其他数据类型被称为引用数据类型
var a = {name:“terry”,age:12}
var a = [18812344321,15912344321];
var a = function(){}
var a = /[abc]def/i
2> 类型检测
typeof a
3> 深拷贝浅拷贝// 浅拷贝【地址拷贝】 // 深拷贝【克隆】
-
-
表达式:操作符 和 操作数组成
1> 算术操作符
+
var result = 1+2
var result =1+true
result = 2当操数中出现了字符串,+运算就变成字符拼接运算
var result=1+‘12’
result=‘112’var result =3-2
*
var result =23
/
var result=23
%
var result=5%22>比较操作符
<
<=
== 等于
将操作数的数据类型转化为同一数据类型进行比较1》基本数据类型的值 2》引用数据类型的值
=== 全等
先比较讲个操作数的数据类型,不一样直接出false,再比较值
1==‘1’
true
1===‘1’
false
//如何比较两个对象的属性是否一致
1.将对象序列化为json字符串
2.对json字符串进行对比3>逻辑运算符 //短路运算符
&&
返回值不一定是boolean类型
true && false // false
true && true // truevar gender ='female' if (gender=='male' && age >18){}; 对于以上代码,由于gender=='male' 对于&&运算已经为false ,无需再进行其他运算 var result ="hello world" && 3; 对于以上代码,"hello world"为true ,整个&&表达式的值取决于后面的3,所以结果为3 var a; 3 && a; //undefined null && a //null var gender = 'female'; var age = 13 ; var result = gender =='male'&& age > 12; 问 age>12 是否被执行 ,如何证明?
||
var result = true || false //true 有真则真
var result = false ||false // false 同假才假var result = 1>2 || 'hello' ; //hello 如上 1>2为false ,但是无法确定整个表达式的值,所以表达式的值取决于第二个表达式的值,将其返回即可 var result = 1<2 || 'hello' ; //true 如上 1<2为true,可以确定整个表达式的值
!true //false
!!true//true
!false /true4>三目运算符
表达式1 ? 表达式 : 表达式3
如果表达式1为真,返回表达式2,如果表达式1为假,返回表达式三var age = 19;
let result = age>16 ? “成年人” : “未成年”; -
流程控制语句
1>分支语句
1.if 分支
if(exp1){
}
当exp1为true或者可以被转换为true的时候,大括号内部的代码会被执行
if(exp1){
}else{
}
当exp1为true,执行if代码块的内容,否则执行else代码块的内容
2.switch 分支
switch(v){
case c1:
...
break;
case c2:
...
break;
...
default:
...
}
v表示变量 c1,c2,c3...表示常量
当V===c1时,执行C1代码中的内容,
3>循环语句
1. for
for(初始化条件;结束条件;累加){
循环体
}
2. while
初始化条件
while(结束判定条件){
迭代
}
3. do-while
初始化条件
do{
迭代
}while(结束判定条件);
4.for-in //用于遍历数组或变量的
for(key in arr){
console.log(arr[k]);
}
- 对象
对象也是一种数据的集合,键值对。
1> 初始化
1 字面量
对象字面量是以{}作为边界,以多个键值对组成,键与键值对通过:隔开,键值对之间通过 , 隔开
var obj ={name:"a",age:"12",gnder:"male"}
2 构造函数模式
使用Object 系统内置的对象构造函数,也可以用自定义构造函数
var obj = new Object();// var obj ={};
obj 是对象,也被称为实例
Object 是类,也被称为构造函数,构造函数时创建对象的模板
2> 属性访问
1. 点访问
var obj ={name:"a",age:"12",gnder:"male"}
var name =obj.name;
obj.name = 'a'
2. 中括号访问
1.obj["name"]
2.var age = "name"
obj[age]
3> 属性遍历
打印出某个对象中的所有属性;
4> 对象序列化
什么是序列化? 将内存中的对象转换为字符串的描述
为什么要序列化? 解决对象在IO中传递的问题,http中只允许传输字符串与字节流,不能传输对象
常规转换
obj.toString()
转换为json字符串
JSON.Stringify()
es6
var qs = require('querystring')
qs.Stringify(obj)
5> Object
所有构造函数的父构造函数,所有的构造函数都直接或间接的构成Object,所有的实例对象都可以调用其构造函数及其父
构造函数的原型中的方法
Object.prototype.toString()
Object.prototype.valueOf()
var obj= {}//var obj = Object();
obj.toString();
arr的构造函数是Object
6>删除属性
1.js对象的属性可以被删除,Java属性不可以删除
2.js对象可以随意添加属性。java性是固定的
3.js对象可以通过字面量及构建函数 来获取,java职能通过类构建
4.当对象属性的值发生变化的时候
7> 自定义属性
var obj = {
name:"a"
}
name 是可以迭代的,是可读可写的
- 数组
用于保存多个值的集合,在数组中,值被称为元素,值可以是任意的数据类型
通过索引访问元素,索引从0开始,数组的长度通过length属性来访问
1> 初始化
1.字面量
var arr =[4,5,8,6,55]
2.构造函数模式
var arr =new Array();
arr[0]="a";
arr[1]="b";
2> 访问
console.log
3> length 属性
length可读可写
arr.length
4> 遍历
for
while
do-while
for-in
Math.random();
5> 数组API //应用程序编程接口
1.Array.*
Array.IsArray()
判断一个变量是否为数组
Array.from()
将一个可迭代对象转换为一个数组对象
Array.of()
将参数中的值做数组的元素
2.Array.prototype.*
Array.prototype.forEach()
Array.prototype.every()
元素是否满足同一个条件
Array.prototype.some()
是否有元素满足一个条件
Array.prototype.filter()
返回回调函数返回true的元素的集合
返回值为数组
Array.prototype.map()
返回回调函数返回值返回的数组
返回值为数组
栈与队列相关方式
Array.prototype.push()
向数组的末尾追加指定的值
返回值为数组长hy度
Array.prototype.pop()
参数:无
返回值为 删除的!栈顶!元素
Array.prototype.shift()
返回值为 删除的!队列!首部的元素
Array.prototype.unshift()
向数组的开始追加指定的值
排序相关
Array.prototype.reverse() //原值也发生改变
反转
Array.prototype.sort() // 原值也发生改变
默认将数组元素转换为字符串。然后排序
允许接受一个比较器函数作为参数,比较器函数接受两个参数
arr.sort(function(a,b){
if(a>b){
return 1;
}else{
return -1;
}
})
如果a>b return 1 ; 升序
如果a>b return -1 ; 降序
截取
slice(begin,end) //原值不改变
splice(begin,number,x,x,x...)//原值改变
返回删除元素组成的数组
begin为开始位置,number为删除元素个数,x,x,。。。。为插入的元素
-
函数
1> 分类
1.普通函数(方法)
2.构造函数(类)
2> 定义
1.函数声明
函数声明与var声明类似,都会有变量的提升,允许在函数声明前调用函数function 函数名(形参){ } eg function fun(a,b){ return a+b; }
2.函数表达式
类似于普通的赋值表达式,变量会提升,但是函数初始化不会被提升 var add =function(a,b){ return a+b; }
3.函数的调用
()
apply
call()4.函数内部属性 //只有在函数的执行过程中,函数的内部属性才能被确定
this
指向当前执行环境对象
与函数的调用方式有关argument 保存函数实参的引用,是一个类数组对象 arguments.callee 指向当前函数 常用于递归
5.箭头函数 (es6)
箭头函数中的this指向包含他的外部函数,一般用于回调函数
6.函数本质
函数是一种特殊对象,默认情况下,一个函数都会有一个原型对象与之对应,
函数中有个指针prototype指向原型,原型对象中有个constractor指向函数,你中有我,我中有你 -
正则表达式
1>初始化
1.字面量
var pattern = /abc/igm
2.构造函数
var pattern =new RegExp(“abc”,“igm”)
2>修饰符
i ignore case 忽略大小写
g global 全局
m multine 多行
3>使用
RegExp.prototype.text()
RegExp.prototype.exec()
4>正则表达式 (入门,熟悉JS中简单的正则,写一写简单的正则)
独立学科,用于匹配字符串,常用于检索,论文查重,爬虫等
1.直接量
/abc/
/123/
/\s/ 空白符
/\S/ 非空白符
/\d/ 数字 /[0-9]/
/\D/ 非数字 /[^0-9]/ // ^相当于非
/\w/ 任意一个字符 /[a-zA-Z0-9]/
/\W/ /^[a-zA-Z0-9]/
2.字符类
/[0-9]/ 匹配0-9中的任意一个字符 // /0-9/匹配0-9
/^[0-9]/ 非数字3.数量词
/\w{5}/ //对于\w模式,重复5次
/(\w\w){3}/ //对 \w\w模式 重复三次 检测6个字符
{n,m} //匹配n到m次
{n,} //匹配n+次
? //匹配0或1次
+ //匹配1或多次
* //匹配0或多次4.贪婪匹配和非贪婪匹配
默认为贪婪匹配//尽可能多的匹配(次数少,匹配的字符多)
如果希望非贪婪匹配,在数量词后添加?(相反)5.选择
url
协议://ip:port/path
http://127.0.0.1:80/index.html
jdbc:mysql://120.0.0.1:3306/cms6.引用
/1 引用第一个分组匹配的结果
/2 引用第二个分组匹配的结果
5> 测试(类似与牛客网的正则表达式网站) -
其他内置函数
包装器数据类型
基本数据类型默认是无法调用Object原型中的方法,为了丰富基本类型的功能,js就实现了自动装
箱功能【当调用基本数据类型变量的方法时,会自动换换位其基本构造函数的实例对象】
Number var a = 3 //a = new Number(a);//自动装箱 a->Number.prototype->Object.prototype Boolean String String 1.与正则有关 String.protptype.split() "hello".split("") String.protptype.search() 返回匹配模式的字符串的索引 String.protptype.match() 返回找到的字符串的数组 String.protptype.replace(a,b) //表示将字符串中的a替换为B 返回值为替换后的结果 2.检索方法 String.protptype.indexOf() String.protptype.lastIndexOf() 3.截取方法 String.protptype.slice(begin,end) 返回截取后的结果,原值不改变 String.protptype.substr(begin,length) 返回截取后的结果,原址不改变 String.protptype.substring(begin,end) 与slice相同 String.protptype.trim() 取消字符串左右两边的空格 4.大小写转化 String.protptype.toUpperCase() String.protptype.toLowerCase() 5.属性 length 6.其他方法 Date 构造函数 var now = new Date(); now.prototype.getTime(); 时间戳,当前时间到格林威治标准时间的毫秒数 now.prototype.getFullYear(); //年 now.prototype. getHours(); //时 now.prototype. getMinutes(); //分 now.prototype. getSconds(); //秒 now.prototype. getDay(); //周几 now.prototype.getDate(); //日期 Math 是一个对象,不是函数 Math.random(); Math.ceil(); //向上舍入 Math.floor() //向下舍入 Math.abs(); //取绝对值 Math.round(); //四舍五入 Math.max(); Math.min();
-
面向对象prototype
1.构造函数的封装
如何创建一个对象
字面量/构造函数(object)–纯对象 只能调用object.prototype中的方法,并且类型无法细分细分类型
特定的对象可以调用特定的方法
1>工厂函数模式
function Person(name,age,gender){
var p =new Object();
p.name=name;
p.age=age;
p.gender=gender;
return p;
}
var p = Person(“tom”,12,“male”);
p.constructor //Object
问题:对象类型无法细分2>构造函数模式
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName=function(){
console.log("my name is ",this.name);
}
}
构造函数用new来调用
this 指向当前实例对象
函数执行完后会将当前函数实例对象返回
var p1 = new Person("tom",15,"male");
//p1指向实例对象
var p2 =Person("lucy",18,"female");
//p2为undefined
解决:对象类型细分问题
问题:函数存储,将函数放到实例对象中,每个实例对象都会有一个独自的函数,无意义且浪费内存
3>构造函数(实例属性)+原型(实例方法,共享属性)
基本属性维护在实例中,共同的方法维护构造函数原型中
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
Person.prototype.sayName = function(){
console.log("my name is",this.name);
}
Person.prototype.sayAge=function(){
console.log("my age is ",this.age);
}
Person.prototype.sayGender=function(){
console.log("my gender is "this.gender);
}
var p=new Person("zk",21,male);
问题:原型方法封装性较差
4> 增强版
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
Person.prototype={
constructor:person,
sayName:function(){
console.log("my name is",this.name);
},
sayAge:function(){
console.log("my age is",this.age);
},
sayGender:function(){
console.log("my gender is "this.gender);
}
}
- 继承
实例对象可以调用其构造函数原型链中的方法
var arr=[1,2,3];
arr->Array.prototype ->Object.prototype
1>借用构造函数
function Animal(name,age){
this.name=name;
this.age=age;
}
Animal.prototype={
constructor:Animal,
sayName:function(){
console.log("its a",name);
},
sayAge:function(){
console.log("its ",age,"years old");
}
}//父类构造函数
function Dog(name,age,gender){
Animal.call(this,name,age); //借用Animal函数的构造函数
//与 this.name=name;this.age=age; 等价
this.gender=gender;
}
2>原型链继承
Dog.prototype=new Animal(); //继承是指就是新建一个被继承类的实例对象
Dog.prototype.constructor = Dog; //然后将新实例对象的构造方法,由指向被继承的构造方法指向新的构造方法
Dog.prototype.sayGender=function(){ //最后添加子类的独有的构造方法,就完成了继承
console.log(this.gender);
}
- dom
js->html/css 页面活动起来(页面的局部更新)
浏览器将html/css转为JS对象,然后让我们通过js操作这些对象
node节点
Node.prototype.childNodes //属性
elment
属性
方法
事件机制
1.三要素
事件源:dom对象(元素节点)
事件处理函数:匿名函数
未来的某一时间执行,由//
事件对象: 记录了事件的详细信息
2.基本概念
1>事件类型
click
dbclick
mouseover //鼠标滑出
mouseenter //鼠标滑入
keyup
keydown
keypress
blur
focus
scroll
...
2> 默认行为事件
a标签/form标签中,我们没有给元素绑定事件,但操作之后有事件行为
3> 事件冒泡
元素存在嵌套关系
<div class="outer">
<div class="center">
<div class="inner">
</div>
</div>
</div>
每层元素都绑定事件处理函数
操作
事件捕获: outer-》center-》inner
事件处理函数的调用默认是按照事件冒泡的顺序调用
事件冒泡:inner-》center -》 outer
4> target(目标元素)
操作的元素
3.事件绑定
事件源.on事件类型=事件处理函数(事件对象){
}
dom.onClick = function(event){
}
绑定方式:
1.onXXX
2.addEventListener()
3.attachEvent()
4.事件对象
event.target()
事件目标元素
event.clientX
event.preventDefault();
禁止默认行为 eg a标签的页面跳转
event.stopPropagation();
5.事件代理
将事件绑定在父元素上
6.jquery实现动态表格
jquery 实际上是对于dom api的封装,是用户使用dom更简洁
业务 js jquery
选择元素 querySelect 选择器
-
bom
js->浏览器
1> 超时调用&间歇调用
setTimeout(function{},1000)
经过1000ms以后调用回调函数,只调用一次,1000ms不可靠var flag = setInterval(function(){
},1000)
每经过1000ms以后调用回调函数,反复调用
2> 弹框 (企业级不会直接使用)
alert 警告框
阻塞代码的运行 一般用来调试代码
prompt 询问框confirm 确认框
3> 打开一个页面
window.href
4>滚动
5>ajax
async javascript and xml
异步的js和xml
主要用于前后台分离开发中数据的交互,占据我们开发的50%以上异步:
function(){
查询A ajax
查询B ajax
查询C ajax
console.log(end);
}
三个查询同时进行,由于网络等原因,返回结果不确定的,因此console.log最先执行实现过程
1.实例化XMLHTTPRequest
var xhr = new XMLHttpRequest()
2.设置请求行
xhr.open(method,url)
3.设置请求头
xhr.setRequestHeader(key,val)
4.设置请求体
请求方式method = "POST"才会传递data
xhr.send(data)
5.监听请求状态
xhr.onreadystatechange = function(){
if(this.readyState= =4){
if(this.status==200){
console.log(this.response);
}
}
}//status 200 ok 500 后端接口异常 404 找不到