JavaScript
1.js事件和作用域
js事件:html页面中每一个元素都可以产生某些触发js函数的事件。这些事件是可以被js侦测到的一种行为,并且js程序能应对这些事件。
常见的html事件
onchange:html元素改变
onclick:用户点击html元素
onmouseover:用户吧鼠标移到html元素上
onmouseout:用户从html元素移开鼠标
onkeydown:用户按下键盘按键
onkeyup:浏览器完成页面的加载
HTML页面完成加载
HTML输入字段被用户更改
HTML按钮被用户点击
设置元素的js事件:行内方法
<element event="JavaScript 代码"></element>
<element event='JavaScript 代码'></element>
<button onclick="getElementById('demo').innerHTML=Date()">
innerHTML属性设置元素的内容
设置元素的事件:内部方法
<button onclick="displayDate()">点击这里 p 标签的内容将被修改</button>
<script>
function displayDate() {
document.getElementById("demo").innerHTML = Date();
}
</script>
js作用域
js中有全局作用域和局部作用域
局部作用域:在函数内声明的变量为局部变量,作用域只在函数内部有效,也只能被函数内部访问。 不同函数中可以声明同名的局部变量,局部变量的生命周期是函数的生命周期。
<script>
myFtn();
function myFtn() {
var lanqiaoxueyuan = "www.lanqiao.cn";
document.getElementById("demo1").innerHTML =
"lanqiaoxueyuan" + " = " + lanqiaoxueyuan;
}
document.getElementById("demo2").innerHTML = typeof lanqiaoxueyuan;//undefined
</script>
全局作用域:在函数外声明的变量。全局变量作用域针对整个全局。网页的所有脚本和函数都能访问它。
<script>
var lanqiaoxueyuan = "www.lanqiao.cn";
myFtn();
function myFtn() {
document.getElementById("demo").innerHTML =
"我能显示 " + lanqiaoxueyuan;
}
</script>
自动全局:如果变量在函数内没有声明(没有使用var关键字),该变量为全局变量。
<script>
myFtn();
// 此处的代码可以把 lanqiaoxueyuan 作为全局变量使用。
document.getElementById("demo").innerHTML =
"我可以显示 " + lanqiaoxueyuan;//没有声明直接使用
function myFtn() {
lanqiaoxueyuan = "www.lanqiao.cn";
}
</script>
js变量生命周期
js变量在声明时开始初始化,局部变量在函数销毁后自动销毁,全局变量在页面关闭后进行销毁
函数参数:只在函数内部起作用,是局部变量
全局变量:window是全局对象,因此任何全局变量都属于window对象,是它的一个属性。
如果没有特殊需求,不要创建全局变量,因为它会覆盖window变量(或函数),任何函数,包括window对象,能覆盖全局变量和函数。
2.js字符串和运算符
js字符串:单引号或者双引号引起来的unicode字符序列。用于存储和操作文本。
str.length
转移符号
通常,js字符串是原始数据,可以使用字符创建。
var lanqiaoxueyuan = "www.lanqiao.cn";
但也可以使用new关键字将字符串定义为一个对象。
var lanqiaoxueyuan = new String("www.lanqiao.cn");
虽然String对象可以创建,但是它会拖慢执行速度,并可能产生其他副作用。
因为字符串与对象、对象与对象无法比较。
js运算符:算术运算符 + - * / % ++(左、右) --(左、右)
赋值运算符: = += -= *= /= %=
字符串+数字、字符串+字符串
3.js的数据类型转换
js六种可包含值的数据类型:
- 字符串String
- 数字Number
- 布尔Boolean
- 对象Object
- 函数function
- 唯一的symbol
三中对象类型:
- 对象Object
- 日期Date
- 数组Array
两种值唯一的数据类型:
- null
- undefined
使用typeof运算符返回变量、对象、表达式的类型
NaN的数据类型是Number
数组Array的数据类型是Object
日期Date的数据类型是Object
null的数据类型是Object
undefined的数据类型是undefined
undefined是null的一种,undefined == null为true
constructor属性用于返回js变量的构造函数
<script>
document.getElementById("demo").innerHTML =
"JACK".constructor +//String()
"<br>" +
(3.14).constructor +//Number()
"<br>" +
false.constructor +//Boolean()
"<br>" +
[1, 2, 3, 4, 5].constructor +//Array()
"<br>" +
{ name: "JACK", age: 36 }.constructor +//Object()
"<br>" +
new Date().constructor +//Date()
"<br>" +
function () {}.constructor;//Function()
</script>
可以通过constructor属性来确定某个对象是否为数组或日期(如果用typeof,都是object)
<script>
var haha = ["Women", "Meitian", "Douyao", "Kaixin"];
document.getElementById("demo").innerHTML = isArray(haha);
function isArray(myArray) {
return myArray.constructor.toString().indexOf("Array") > -1;
}
</script>
js类型转换
js类型转换有两种方式:使用js函数、js自身自动转换
数字转字符串:全局String()方法、number.toString()
布尔值转字符串:全局String()方法、boolean.toString()
日期转字符串:Date()返回字符串、String()
字符串转数字:
全局Number():
字符串为数值,可以转换成数字、空字符串转换为0、其他字符串转换为NaN(非数值类型)
Number("3.14"); // 返回 3.14
Number(" "); // 返回 0
Number(""); // 返回 0
Number("99 88"); // 返回 NaN
一元运算符+:
var a = "6";//String
var b = +a;//Number
document.getElementById("demo").innerHTML =
typeof a + "<br>" + typeof b;
使用+可以String转换为Number,如果转换不成功会变成NaN
布尔值转数字:false为0 true为1
全局Number()方法
日期转数字:转换为毫秒数
全局Number()方法,等同于d.getTime()
自动类型转换:
console.log(5 + null);//5 null转为0
console.log("5" + null);//5null null转为“null”
console.log("5" + 1);//51 1转为“1”
console.log("5" - 1);//4 “5”转为5
自动转为字符串:
当尝试输出一个对象或变量时,会自动调用变量的toString()方法
布尔值与字符串:“” “ ”为false 有值的字符串为true
NaN为false ±Infinity为true
“”为数字0
[]为数字0,“”,true
[20]为数字20,“20”,true
function(){}为NaN,true
null为数字0,false
undefined为NaN,false
4.js的正则表达式
js的regex语法:/pattern/modifiers
var patt = /lanqiaoxueyuan/i;
js的正则表达式经常使用两个字符串方法:
search():返回匹配的位置
replace():返回模式被替换出修改后的字符串
test():解析字符串,如果符合正则表达式返回true,否则返回false
var str = "Search lanqiaoxueyuan";
var a = str.search(/lanqiaoxueyuan/i);//7
var str = document.getElementById("demo").innerHTML;
var txt = str.replace(/lanqiaoxueyuan/i, "www.lanqiao.cn");
var a = new RegExp("f");
a.test(
"Attitude determines life, and should not let life determine your attitude!"
);
var patt1 = new RegExp("f");
patt1.exec(
"Attitude determines life, and should not let life determine your attitude!"
);
regex修饰符:
i 执行对大小写不敏感的匹配
g 执行全局匹配
m 执行多行匹配
regex常用模式:
(x|y):以|分割的选项
\d:数字
\w:数字、字母、下划线
\b:单词边界
\uxxxx:Unicode(16进制)
\s:空白字符
量词:
n+ 至少一个n
n* 任意n
n? 零个或一个n
5.原型
js中给函数提供了一个对象类型的属性,叫做Prototype(原型)
原型归所有函数所有,他不用创建 是默认存在存在的
function Car(){
}
var c1 = new Car();
var c2 = new Car();
Car.prototype.name = "BMW";
console.log(c1.name);
console.log(c2.name);
js提供了这样的一种机制,如果是通过构造函数创建对象,当访问你的属性在对象中没有找到,则去创建对象的构造函数中找,如果能找到,也相当于对象拥有这个属性
原型的作用就是为类(函数)提供了一个公共区域,在这个公共区域声明的属性和方法能够被所有通过这个类创建的对象所访问到。
function Car(name,speed,ability){
this.name = name;
this.speed = speed;
this.ability = ability;
}
Car.prototype.showAbility= function(){
console.log(this.ability);
}
var c1 = new Car("BMW",240,"坐宝马");
var c2 = new Car("BZ",300,"开奔驰");
c1.showAbility();
c2.showAbility();
原型是js为所有函数所创建的一个对象类型的属性,原型当中的属性和方法被所有的通过这个函数所创建的所有对象共享。
结构: 原型是一个对象,在原型中通常拥有两个属性
1 构造器: constructor 该属性指向这个函数本身
2 原型指向
__proto__该属性指向原型本身,提供给通过类创建的对象使用
作用: 原型用来创建类的共有属性和共有方法,为创建对象服务
优点: 节约内存空间,不必为每一个对象分配共有属性和共有方法的内存
缺点: 原型中不能保存数组这类引用类型的数据,因为地址的传递的问题 会导致出现修改的连锁变换。
6.原型链
构造函数的属性prototype可以设置共有属性和共有方法
对象拥有__proto__和constructor属性,但是函数也是一种对象,所以函数也有这两种属性
__proto__是由一个对象指向一个对象,即指向他们的原型对象(父对象)。proto 的作用是,当对象找一个属性没找到时,就去它的父对象里找,再往父对象的父对象里找。最后形成了一条原型链。
prototype是函数独有的,从一个函数指向一个对象,也就是这个函数创建的实例的原型对象,即f1.proto===Foo().prototype。prototype属性的作用是包含可以让特定类型的所有实例共享的属性和方法。
constructor是对象独有的,从一个对象指向一个函数,含义就是指向该对象的构造函数。每个对象都有构造函数,Function的构造函数就是它自己。所以constructor的重点就是Function这个函数。
console.log(c1.__proto__);//获取到c1的构造函数的原型
console.log(c1.__proto__===Car.prototype);//Car.prototype,true
console.log(c1.__proto__.__proto__);//获取到对象的原型,所有对象的原型即Object()定义的公共属性和方法
console.log(c1.__proto__.__proto__===Object.prototype);//Object.prototype,true
console.log(c1.__proto__.__proto__.__proto__);//Object.prototype没有公共属性
console.log(c1.__proto__.__proto__.__proto__);
console.log(new Object().__proto__);//object对象.__proto__===Object()的原型
console.log(new Object().constructor.prototype);//Object()的原型
console.log(new Object().__proto__.__proto__);
console.log(Object.prototype.constructor.prototype);//如果一直对Object对象调用构造方法再获取公共属性,会一直套娃。