文章目录
- 1.正则表达式(规则表达式.RegularExpression)
- 语法:
- 在构造函数中可以传递一个匹配模式作为第二个参数:
- i :忽略大小写
- g :全局匹配模式
- 用字面量来创建正则表达式
- 或: | 、[ ]
- 除了...以外: ^
- 2.字符串和正则相关方法
- split( )
- search( )
- match( )
- replace( )
- 3.正则表达式语法(上)
- 量词 {}
- + (至少一个,相当于{1,})
- * (0个或多个,相当于{0,})
- ? (0个或者1个,相当于{0,1})
- ^ (表示开头)
- $ (表示结尾)
- 4.正则表达式语法(下)
- \w(任意字母,数字,下划线,即 [0-9A-z_])
- \W(除了字母,数字,下划线,即 [^0-9A-z_])
- \d(任意的数字,即 [0-9])
- \D(除了数字,即 [^0-9])
- \s(空格)
- \S(除了空格)
- \b(单词边界)
- \B(除了单词边界)
- 邮件的正则表达式
- 5.this
- 6.使用工厂方法创建对象
- 7.构造函数
- 执行流程
- instanceof 函数(实例)
- this情况
- 8.构造函数修改
- 经原型对象修改后
- 9.原型对象
- prototype 属性
- 往原型对象中添加属性和方法
- 原型对象也是对象,所以原型对象也有原型对象
- 再次总结this情况
- 1.以函数形式调用,this永远都是window
- 2.以方法的形式调用,this是调用方法的对象
- 3.以构造函数的形式调用,this是新创建的这个对象
- 4.使用call( ) 和 apply( )形式调用,this是指定的对象
- 5.以响应函数的形式调用,this指向的是响应函数的对象
- 10.let:定义变量
- (1)必须先定义再使用
- (2)变量不能重复声明
- (3)块级作用域{ }
- 11.const:定义常量
- (1)必须先定义再使用
- (2)变量不能重复声明
- (3)块级作用域{ }
- (4)定义后需要赋值,如果不赋值为undefined,后续无法重新再赋值
- 12.箭头函数
- 省略小括号
- 省略大括号
- 应用案例:
- arguments
- 再次复习,把伪数组转化为数组
- 箭头函数的this是父级作用域的(或者说没有this)
- 13.解构赋值
- 快速从数组中获取元素
- 快速从对象中获取元素
- 14.对象简写
- 15.展开运算符
- 展开数组
- 形参
- 实参
- 找最值
- 伪数组转换
- 展开对象
- 16.模块化语法
- 17.工厂的方式创建对象
- 18.构造函数
- 执行流程
- instanceof 函数(实例)
- 19.原型对象
- prototype 属性
- 往原型对象中添加属性和方法
- 原型对象也是对象,所以原型对象也有原型对象
- 小练习
- 20.ES6-class
- 21.面向对象继承
- 22.es6继承
- 23.ajax
- 24.ajax案例
- 25.同步异步
1.正则表达式(规则表达式.RegularExpression)
正则表达式用于定义一些字符串的规则,计算机可以根据正则表达式,来检查一个字符串是否规则,或者将字符串中符合规则的内容提取出来
语法:
var 变量 = new RegExp(" 正则表达式 "," 匹配模式 ") ;
正则表达式的方法:
test( )
使用这个方法可以用来检查一个字符串是否符合正则表达式的规则,如果符合返回true ,如果不符合返回flase
例如以下形式可以用来检查一个字符串是否含有“a”
var reg = new RegExp("a");
console.log(reg);
console.log(reg.test("bab")) ;
console.log(reg.test("bcb")) ;
在构造函数中可以传递一个匹配模式作为第二个参数:
i :忽略大小写
var reg = new RegExp("ac","i");
console.log(reg);
console.log(reg.test("ACbbb")) ;
g :全局匹配模式
var reg = new RegExp("ac","g");
console.log(reg);
console.log(reg.test("aCbb")) ;
用字面量来创建正则表达式
语法:
var 变量 = / 正则表达式 / 匹配模式
或: | 、[ ]
举例:创建一个正则表达式来检查一个字符串中是否含有小写字母
(使用 | 来表示或者的意思)( [ ]里面的内容也是或的关系,即也能用来表示或者)
var reg = /[a-z]/;
console.log(reg.test("asduwgdiuwhdj"));
所以:
[a-z]表示任意小写字母
[A-Z]表示任意大写字母
[A-z]表示任意一个字母
举例:检查字符串中是否含有 abc或alc或auc或aec
var reg = /a[blue]c/;
console.log(reg.test("abc"));
console.log(reg.test("alc"));
console.log(reg.test("auc"));
console.log(reg.test("aec"));
console.log(reg.test("ablc"));
除了…以外: ^
举例:检查一个字符串是否含有除了 a或b 以外的
var reg = /[^abc]/;
console.log(reg.test("acc"));
console.log(reg.test("abcoo"));
console.log(reg.test("aoo"));
console.log(reg.test("p"));
console.log(reg.test("abp"));
举例:检查一个字符串是否含有除了数字以外的
var reg = /[^0-9]/;
console.log(reg.test("123"));
console.log(reg.test("a98498"));
console.log(reg.test("abc123oo"));
其余有关 JavaScript RegExp 对象 的相关资料查询网址:
https://www.runoob.com/jsref/jsref-obj-regexp.html
2.字符串和正则相关方法
split( )
可以将一个字符串拆分成一个数组
方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆分数组
这个方法即使不设置全局匹配,也会对每一个指定内容进行拆分数组
var str = "1a2b3c4d5e6f7" ;
var res = str.split("c");
console.log(res);
res = str.split(/[A-z]/);
console.log(res);
search( )
可以搜索字符串中是否含有指定内容
如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1
它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串
search( ) 只会查找第一个遇见的,即使设置了全局匹配
var str = "hello abb hello adc hellow aec";
var res = str.search(/a[bde]c/);
console.log(res);
运行结果为:
16
match( )
可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
默认情况下我们的 match 只会找到第一个符合要求的内容,找到以后就停止检索,我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
可以为正则表达式设置多个匹配模式,且顺序无所谓
match( ) 会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
var str = "1a2b3c4d5e6f7";
var res = str.match(/[A-z]/g);
console.log(res);
console.log(Array.isArray(res));
console.log(res[1]);
replace( )
可以将我们字符串中的指定内容替换为新的内容
参数:
1.被替换的内容,可以接收一个正则表达式作为参数
2.新的内容
默认只会替换第一个
3.正则表达式语法(上)
量词 {}
通过量词可以设置一个内容出现的次数
量词只对他前面的一个内容起作用
{n}正好出现 n 次
{m,n}出现m到n次
{m,}出现m次以上
var reg = /a{3}/;
console.log(reg.test("aaabc"));
reg = /ab{3}/
console.log(reg.test("ababab"));
console.log(reg.test("acabbb"));
reg = /(ab){3}/;
console.log(reg.test("ababab"));
reg = /ab{2,4}c/;
console.log(reg.test("abbc"));
+ (至少一个,相当于{1,})
var reg = /ab+c/;
console.log(reg.test("abc"));
console.log(reg.test("abbbbc"));
* (0个或多个,相当于{0,})
var reg = /ab*c/;
console.log(reg.test("ac"));
console.log(reg.test("abbbbc"));
? (0个或者1个,相当于{0,1})
var reg = /ab?c/;
console.log(reg.test("ac"));
console.log(reg.test("abc"));
^ (表示开头)
检查一个字符串是否以 a 开头
var reg = /^a/;
console.log(reg.test("abc"));
$ (表示结尾)
检查一个字符串是否以 a 结尾
var reg = /a$/;
console.log(reg.test("xxbca"));
注意:
如果在正则表达式中同时使用 ^ 和 $ 则要求字符串必须完全符合正则表达式
var reg = /^a$/;
console.log(reg.test("aaa"));
console.log(reg.test("a"));
4.正则表达式语法(下)
. :表示任意字符
在正则表达式中使用 \ 作为转义字符
可以用 . 来表示 " . "
检查一个字符串中是否含有 " . "
var reg = /\./;
console.log(reg.test("abc.abc"));
检查一个字符串中是否含有 \
var reg = /\\/;
console.log(reg.test("abc\\abc"));
\w(任意字母,数字,下划线,即 [0-9A-z_])
\W(除了字母,数字,下划线,即 [^0-9A-z_])
\d(任意的数字,即 [0-9])
\D(除了数字,即 [^0-9])
\s(空格)
\S(除了空格)
\b(单词边界)
var reg = /\bboy\b/;
console.log(reg.test("boy girl"));
\B(除了单词边界)
去除一个字符串前面和后面的空格
var str = " he llo ";
console.log(str);
console.log(str.replace(/\s/g,""));
console.log(str.replace(/^\s*|\s*$/g,""));
邮件的正则表达式
var youjian = prompt("请输入电子邮件:");
var reg = /^[\w]*\.*[\w]*@[A-z0-9]+\.[A-z]{2,5}\.[A-z]{2,5}$/g;
console.log(youjian);
console.log(reg.test(youjian));
5.this
解析器在调用函数每次都会向函数内部传递进一个隐含的参数
这个隐含的参数就是 this,this 指向的是一个对象
这个对象我们称为函数执行的 上下文对象,根据函数调用的方式不同会指向不同的对象
1.以函数的形式调用的时候 this 是 window
2.以方法的形式调用的时候 this 是 调用方法的那个对象
重点:this会根据调用形式的不同发生改变!!!
function fun() {
// console.log("a = "+a,"b = "+b);
console.log(this);
console.log(this.name);
}
//以窗口的形式调用,this是window
fun()
var name = "全局的name属性"
//以方法的形式调用,this是调用方法的对象
var obj = {
name:"猴子",
sayName:fun
}
obj.sayName();
var obj2 = {
name:"牛马",
sayName:fun
}
obj2.sayName();
利用 this 根据调用的不同变成不同的值
//创建一个name变量
var name = "全局name";
//创建一个 fun() 函数
function fun() {
console.log(name);
console.log(this.name);
console.log("\n");
}
//创建两个对象
var obj = {
name:"猴子",
sayName:fun
}
var obj2 = {
name:"牛马",
sayName:fun
}
fun();
//这边希望调用 obj.sayName() 时可以输出obj的name
obj.sayName();
//这边希望调用 obj2.sayName() 时可以输出obj2的name
obj2.sayName();
6.使用工厂方法创建对象
//使用工厂方法创建对象
// 通过该方法可以大批量的创建对象
function createPreson(name,age,gender){
//创建一个新对象
var obj = new Object();
//向对象中添加属性
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
}
//将新对象返回
return obj;
}
var obj2 = createPreson("lkj",20,"男");
var obj3 = createPreson("猪儿虫",20,"女");
var obj4 = createPreson("牛马",18,"男");
console.log(obj2);
console.log(obj3 );
console.log(obj4);
obj3.sayName();
使用工厂方法创建对象,使用的构造函数都是Objec
所以创建的对象都是Object这个类型
导致我们无法区分出多种不同的对象
function createPreson(name,age,gender){
//创建一个新对象
var obj = new Object();
//向对象中添加属性
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
}
//将新对象返回
return obj;
}
var obj2 = createPreson("lkj",20,"男");
var obj3 = createPreson("猪儿虫",20,"女");
var obj4 = createPreson("牛马",18,"男");
console.log(obj2);
// console.log(obj3 );
// console.log(obj4);
// obj3.sayName();
//创建一个狗的对象
function createDog(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayHello = function(){
alert(this.name+":汪汪汪~ ~ ~");
}
return obj;
}
var dog2 = createDog("小狗一号",3);
var dog3 = createDog("小狗二号",5);
console.log(dog2);
console.log(dog3);
// obj2.sayHello();
7.构造函数
创建一个构造函数专门用来创建 Preson 对象
构造函数就是一个普通的函数,创建方式和普通函数没有区别
不同的是构造函数习惯上首字母大写
构造函数和普通函数的区别就是调用方式不同
普通函数是直接调用,而构造函数需要使用new关键字来调用
function Preson(){
}
var per1 = Preson();
var per2 = new Preson();
console.log( per1);
console.log( per2);
执行流程
构造函数的执行流程:
1.立刻创建一个新的对象
2.将新建对象设置为函数中的 this ,在构造函数中可以使用 this 来引用新建的对象
3.逐行执行函数中的代码
4.将新建对象作为返回值返回
使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类
我们将通过一个构造函数创建的对象,称为是该类的实例
function Preson(name ,age ,gender ){
// alert(this);
this.name = name,
this.age = age,
this.gender = gender,
this.sayName = function(){
alert(this.name);
}
}
var per1 = new Preson("lkj",20,"男");
var per2 = new Preson("猪儿虫",20,"女");
var per3 = new Preson("牛马",18,"男");
console.log(per1);
console.log(per2);
console.log(per3);
function Dog(name ,age ){
this.name = name;
this.age = age;
this.sayHello = function(){
alert(this.name+":汪汪汪~ ~ ~");
}
}
var dog1 = new Dog("小狗一号",3);
var dog2 = new Dog("小狗二号",5);
var dog3 = new Dog("小狗三号",7);
console.log(dog1);
console.log(dog2);
console.log(dog3);
instanceof 函数(实例)
使用 instanceof 函数可以检查一个对象是否是一个类的实例
语法:
对象 instanceof 构造函数
如果是返回 true ,如果不是返回 false
例如:
function Preson(name ,age ,gender ){
// alert(this);
this.name = name,
this.age = age,
this.gender = gender,
this.sayName = function(){
alert(this.name);
}
}
var per1 = new Preson("lkj",20,"男");
var per2 = new Preson("猪儿虫",20,"女");
var per3 = new Preson("牛马",18,"男");
console.log(per1);
console.log(per2);
console.log(per3);
function Dog(name ,age ){
this.name = name;
this.age = age;
this.sayHello = function(){
alert(this.name+":汪汪汪~ ~ ~");
}
}
var dog1 = new Dog("小狗一号",3);
var dog2 = new Dog("小狗二号",5);
var dog3 = new Dog("小狗三号",7);
console.log(dog1);
console.log(dog2);
console.log(dog3);
console.log(per1 instanceof Preson);
console.log(per2 instanceof Dog);
console.log(dog1 instanceof Dog);
console.log(dog1 instanceof Preson);
所有的对象都是 Object 的后代
所有任何的对象来进行 instanceof 检查时都会返回 true
this情况
1.当以函数的形式调用时,this 是 window
2.当以方法的形式调用时,this 是 调用这个方法的对象
3.当以构造函数形式调用时,this 就是新创建的哪个对象
8.构造函数修改
在Preson构造函数中,为每一个对象都添加了一个sayName方法
目前我们的方法是在构造函数内部创建的,也就是构造函数每执行一次就会创建一个新的sayName方法,即所有实例的sayName都是唯一的
这样也就导致构造函数执行一次就会创建一个新的方法
执行10000次就会创建10000个新的方法,而10000个方法都是一模一样的
这是完全没必要的,完全可以使所有的对象共享一个方法
// 创建一个Preson构造函数
function Person(name ,age ,gender ){
this.name = name;
this,age = age;
this.gender = gender;
//向对象中添加一个方法
this.sayName = fun;
}
// 将sayName方法在全局作用域中定义
function fun(){
alert("hello"+this.name);
}
//创建一个Preson实例
var pre1 = new Person("鸵鸟",20,"女");
var pre2 = new Person("猴子",20,"男");
pre1.sayName();
pre2.sayName();
经原型对象修改后
function Person(name ,age ,gender ){
this.name = name;
this,age = age;
this.gender = gender;
}
Person.prototype.sayName = function(){
alert("hello:"+this.name);
}
//创建Preson实例
var pre1 = new Person("鸵鸟",20,"女");
var pre2 = new Person("猴子",20,"男");
pre1.sayName();
pre2.sayName();
9.原型对象
prototype 属性
原型(prototype)
我们创建的每一个函数,解析器都会向函数中添加一个属性 prototype
这个属性对应这一个对象,这个对象就是我们所谓的原型对象
当函数作为普通函数调用 prototype没有任何作用
当函数以构造函数形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过__proto__
来访问该属性
function MyClass () {
}
var mc1 = new MyClass();
var mc2 = new MyClass();
console.log(MyClass.prototype);
console.log(mc1.__proto__);
console.log(mc2.__proto__);
console.log(mc1.__proto__ == mc2.__proto__);
console.log(mc1.__proto__ == MyClass.prototype);
console.log(mc2.__proto__ == MyClass.prototype);
往原型对象中添加属性和方法
原型对象就相当于一个公共区域,所有同一个类的实例都可以访问到这个对象
我们可以将对象共有的内容,统一设置到原型对象中
当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
所以以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法
function MyClass () {
}
var mc1 = new MyClass();
var mc2 = new MyClass();
console.log(MyClass.prototype);
console.log(mc1.__proto__);
console.log(mc2.__proto__);
console.log(mc1.__proto__ == mc2.__proto__);
console.log(mc1.__proto__ == MyClass.prototype);
console.log(mc2.__proto__ == MyClass.prototype);
MyClass.prototype.a = "原型对象的a";
mc1.a = "mc1的a";
MyClass.prototype.sayHello = function(){
alert("原型跟你:hello");
}
mc1.sayHello = function(){
alert("mc1跟你:hello");
}
console.log(mc1.a);
console.log(mc2.a);
mc1.sayHello();
mc2.sayHello();
原型对象也是对象,所以原型对象也有原型对象
当我们在使用对象的属性或者方法时,会先在自身中寻找,自身中如果有,则直接使用,如果没有则去原型对象中寻找,如果原型对象中有则使用,如果原型对象中没有,则去原型对象的原型对象中寻找,直到找到Object 对象的原型,Object 对象的原型没有原型
function MyClass(name){
}
MyClass.prototype.name = "原型的name";
var mc1 = new MyClass("鸵鸟");
console.log(mc1.name)
//使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
console.log("name" in mc1);
// 可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
console.log(mc1.hasOwnProperty("name"));
console.log(mc1.__proto__.hasOwnProperty("hasOwnProperty"));
console.log(mc1.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
再次总结this情况
1.以函数形式调用,this永远都是window
2.以方法的形式调用,this是调用方法的对象
3.以构造函数的形式调用,this是新创建的这个对象
4.使用call( ) 和 apply( )形式调用,this是指定的对象
5.以响应函数的形式调用,this指向的是响应函数的对象
10.let:定义变量
(1)必须先定义再使用
let a = 1
console.log(a)
(2)变量不能重复声明
let b = 123
let b = 456//报错
console.log(b)
(3)块级作用域{ }
if(1){
let a = 123
}
console.log(a)//报错,无法访问到块级内部的a
11.const:定义常量
(1)必须先定义再使用
(2)变量不能重复声明
(3)块级作用域{ }
(4)定义后需要赋值,如果不赋值为undefined,后续无法重新再赋值
12.箭头函数
省略小括号
let b = () => {
console.log(2)
}
//只有一个形参的时候可以省略括号
let c = m => {
console.log(m)
}
c("111")
省略大括号
//代码中只有一句话或者一个返回值的时候可以省略大括号
let sum = (a) => console.log(a*10)
sum(2)//20
let text = () => ({ name: "lkj" })
console.log(text())
应用案例:
简单的将数组中的元素遍历出后进行标签创建的添加
// 应用举例
let list = ["a", "b", "c", "d", "e"]
let newList = list.map(item => `<li>${item}</li>`)
console.log(newList)
arguments
可以把实参保存进入一个伪数组
let text = function(){
console.log(arguments)
console.log(arguments[0],arguments[1],arguments[2],)
}
text("a","b","c")
text(1,2,3)
再次复习,把伪数组转化为数组
Array.from(arguments)
箭头函数的this是父级作用域的(或者说没有this)
13.解构赋值
快速从数组中获取元素
var arr = ["aaa","bbb","ccc"]
var [a,b,c] = arr
console.log(arr)
console.log(a,b,c)
var arr = [1,2,[3,4,[5]]]
var [a,b,[c,d,[e]]] = arr
console.log(arr)
console.log(e)
快速从对象中获取元素
var obj = {
name:"aaa",
age:10,
location:"shaxian"
}
如果对应的属性已经存在可以使用 :my.... 的方式
let{name,age,location:mylocation} = obj
console.log(obj)
console.log(mylocation)
14.对象简写
<input type="text" id="myusername">
<input type="password" id="mypassword">
<button id="btn">btn</button>
<script>
let myusername = document.getElementById("myusername")
let mypassword = document.getElementById("mypassword")
let btn = document.getElementById("btn")
btn.onclick = function(){
let username = myusername.value
let password = mypassword.value
let obj = {
username,
password,
}
console.log(obj)
}
</script>
15.展开运算符
展开数组
let a = [1,2,3]
let b = [3,4,5]
let c = [...a,...b]
console.log(c)
let d = [...a]
console.log(d)
形参
let text = (...arr)=>{
console.log(...arr)
console.log(arr)
}
text(1,2,3,4,5)
实参
let arr = [1,2,3]
let text = (a,b,c)=>{
console.log(a,b,c)
}
text(...arr)
找最值
let arr = [1,5,4,8,6,1,4,7,65,1,4,85,56,57]
let max = Math.max(...arr)
console.log(max)
伪数组转换
function text(){
let arr = [...arguments]
console.log(arr)
}
text(1,2,3,4,5)
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
</ul>
let lis = document.getElementsByTagName("li")
console.log(lis)
let lisArr = [...lis]
console.log(lisArr)
展开对象
let obj1 = {
aaa:1,
bbb:2
}
let obj2 = {
aaa:4,
ccc:3
}
let obj3 = {
...obj1,
...obj2
}
console.log(obj3)
16.模块化语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./js/C.js" type="module"></script>
<!-- 导入 -->
<script type="module">
// import { A1, A2, text as A_text} from './js/A.js'
import { A1, A2, text as A_text} from './js/A.js'
import { B1, B2, text as B_text} from './js/B.js'
A1()
A2()
B1()
B2()
A_text()
B_text()
</script>
</body>
</html>
function A1() {
console.log("A1")
}
function A2() {
console.log("A2")
}
function text() {
console.log("A text")
}
function no() {
console.log("no")
}
//导出
export { A1, A2, text, no }
function B1() {
console.log("B1")
}
function B2() {
console.log("B2")
}
function text() {
console.log("B text")
}
function no() {
console.log("no")
}
//导出
export { B1, B2, text, no }
import { A1 } from './A.js'
import { B1 } from './B.js'
A1()
B1()
17.工厂的方式创建对象
//使用工厂方法创建对象
// 通过该方法可以大批量的创建对象
function createPreson(name,age,gender){
//创建一个新对象
var obj = new Object();
//向对象中添加属性
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
}
//将新对象返回
return obj;
}
var obj2 = createPreson("lkj",20,"男");
var obj3 = createPreson("猪儿虫",20,"女");
var obj4 = createPreson("牛马",18,"男");
console.log(obj2);
console.log(obj3 );
console.log(obj4);
obj3.sayName();
使用工厂方法创建对象,使用的构造函数都是Objec
所以创建的对象都是Object这个类型
导致我们无法区分出多种不同的对象
function createPreson(name,age,gender){
//创建一个新对象
var obj = new Object();
//向对象中添加属性
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
}
//将新对象返回
return obj;
}
var obj2 = createPreson("lkj",20,"男");
var obj3 = createPreson("猪儿虫",20,"女");
var obj4 = createPreson("牛马",18,"男");
console.log(obj2);
// console.log(obj3 );
// console.log(obj4);
// obj3.sayName();
//创建一个狗的对象
function createDog(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayHello = function(){
alert(this.name+":汪汪汪~ ~ ~");
}
return obj;
}
var dog2 = createDog("小狗一号",3);
var dog3 = createDog("小狗二号",5);
console.log(dog2);
console.log(dog3);
// obj2.sayHello();
18.构造函数
创建一个构造函数专门用来创建 Preson 对象
构造函数就是一个普通的函数,创建方式和普通函数没有区别
不同的是构造函数习惯上首字母大写
构造函数和普通函数的区别就是调用方式不同
普通函数是直接调用,而构造函数需要使用new关键字来调用
function Preson(){
}
var per1 = Preson();
var per2 = new Preson();
console.log( per1);
console.log( per2);
执行流程
构造函数的执行流程:
1.立刻创建一个新的对象
2.将新建对象设置为函数中的 this ,在构造函数中可以使用 this 来引用新建的对象
3.逐行执行函数中的代码
4.将新建对象作为返回值返回
使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类
我们将通过一个构造函数创建的对象,称为是该类的实例
function Preson(name ,age ,gender ){
// alert(this);
this.name = name,
this.age = age,
this.gender = gender,
this.sayName = function(){
alert(this.name);
}
}
var per1 = new Preson("lkj",20,"男");
var per2 = new Preson("猪儿虫",20,"女");
var per3 = new Preson("牛马",18,"男");
console.log(per1);
console.log(per2);
console.log(per3);
function Dog(name ,age ){
this.name = name;
this.age = age;
this.sayHello = function(){
alert(this.name+":汪汪汪~ ~ ~");
}
}
var dog1 = new Dog("小狗一号",3);
var dog2 = new Dog("小狗二号",5);
var dog3 = new Dog("小狗三号",7);
console.log(dog1);
console.log(dog2);
console.log(dog3);
instanceof 函数(实例)
使用 instanceof 函数可以检查一个对象是否是一个类的实例
语法:
对象 instanceof 构造函数
如果是返回 true ,如果不是返回 false
例如:
function Preson(name ,age ,gender ){
// alert(this);
this.name = name,
this.age = age,
this.gender = gender,
this.sayName = function(){
alert(this.name);
}
}
var per1 = new Preson("lkj",20,"男");
var per2 = new Preson("猪儿虫",20,"女");
var per3 = new Preson("牛马",18,"男");
console.log(per1);
console.log(per2);
console.log(per3);
function Dog(name ,age ){
this.name = name;
this.age = age;
this.sayHello = function(){
alert(this.name+":汪汪汪~ ~ ~");
}
}
var dog1 = new Dog("小狗一号",3);
var dog2 = new Dog("小狗二号",5);
var dog3 = new Dog("小狗三号",7);
console.log(dog1);
console.log(dog2);
console.log(dog3);
console.log(per1 instanceof Preson);
console.log(per2 instanceof Dog);
console.log(dog1 instanceof Dog);
console.log(dog1 instanceof Preson);
所有的对象都是 Object 的后代
所有任何的对象来进行 instanceof 检查时都会返回 true
19.原型对象
prototype 属性
原型(prototype)
我们创建的每一个函数,解析器都会向函数中添加一个属性 prototype
这个属性对应这一个对象,这个对象就是我们所谓的原型对象
当函数作为普通函数调用 prototype没有任何作用
当函数以构造函数形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过__proto__
来访问该属性
function MyClass () {
}
var mc1 = new MyClass();
var mc2 = new MyClass();
console.log(MyClass.prototype);
console.log(mc1.__proto__);
console.log(mc2.__proto__);
console.log(mc1.__proto__ == mc2.__proto__);
console.log(mc1.__proto__ == MyClass.prototype);
console.log(mc2.__proto__ == MyClass.prototype);
往原型对象中添加属性和方法
原型对象就相当于一个公共区域,所有同一个类的实例都可以访问到这个对象
我们可以将对象共有的内容,统一设置到原型对象中
当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
所以以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法
function MyClass () {
}
var mc1 = new MyClass();
var mc2 = new MyClass();
console.log(MyClass.prototype);
console.log(mc1.__proto__);
console.log(mc2.__proto__);
console.log(mc1.__proto__ == mc2.__proto__);
console.log(mc1.__proto__ == MyClass.prototype);
console.log(mc2.__proto__ == MyClass.prototype);
MyClass.prototype.a = "原型对象的a";
mc1.a = "mc1的a";
MyClass.prototype.sayHello = function(){
alert("原型跟你:hello");
}
mc1.sayHello = function(){
alert("mc1跟你:hello");
}
console.log(mc1.a);
console.log(mc2.a);
mc1.sayHello();
mc2.sayHello();
原型对象也是对象,所以原型对象也有原型对象
当我们在使用对象的属性或者方法时,会先在自身中寻找,自身中如果有,则直接使用,如果没有则去原型对象中寻找,如果原型对象中有则使用,如果原型对象中没有,则去原型对象的原型对象中寻找,直到找到Object 对象的原型,Object 对象的原型没有原型
function MyClass(name){
}
MyClass.prototype.name = "原型的name";
var mc1 = new MyClass("鸵鸟");
console.log(mc1.name)
//使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
console.log("name" in mc1);
// 可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
console.log(mc1.hasOwnProperty("name"));
console.log(mc1.__proto__.hasOwnProperty("hasOwnProperty"));
console.log(mc1.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
小练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box1">
<h1></h1>
<ul></ul>
</div>
<script>
let lol = {
title: 'LOL',
list: ['上', '中', '野', '下', '辅']
}
function CreateList(ele, obj) {
this.ele = document.querySelector(ele)
this.title = obj.title
this.list = obj.list
}
CreateList.prototype.render = function () {
// 渲染页面
let h1 = this.ele.querySelector("h1")
let ul = this.ele.querySelector("ul")
h1.innerHTML = this.title
ul.innerHTML = this.list.map(item => `<li>${item}</li>`).join("")
console.log(h1)
console.log(ul)
}
let obj1 = new CreateList('.box1', lol)
console.log(obj1)
obj1.render()
</script>
</body>
</html>
20.ES6-class
function CreateObjOld(name){
this.name = name
}
let oldObj1 = new CreateObjOld("旧的")
console.log(oldObj1)
class CreateObj{
// 构造器函数
constructor(name){
this.name = name
}
}
let obj1 = new CreateObj("一号")
console.log(obj1)
21.面向对象继承
function Person(name, age) {
this.name = name,
this.age = age
}
Person.prototype.say = function () {
console.log(this.name ,": hello")
}
function Student(name, age, grade) {
Person.call(this,name,age)//继承属性 --- 把Person的this改变成Student的this
// Person.apply(this,[name,age])
this.grade = grade
}
Student.prototype = new Person()//用于继承原型的方法
Student.prototype.printGrade = function(){
console.log(this.name,this.grade)
}
//覆盖
// Student.prototype.say = function(){
// console.log(this.name ,": hello")
// console.log(this.name ,": 您好")
// }
//增强原来的方法
Student.prototype.say2 = function(){
this.say()
console.log(this.name ,": 您好")
}
var obj = new Student("lkj",18,100)
console.log(obj)
obj.say2()
obj.printGrade()
22.es6继承
//父类
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
say() {
console.log(this.name, "hello")
}
}
//子类
//extends 原型继承
class Student extends Person {
//继承属性
constructor(name, age, greda) {
super(name, age)
this.greda = greda
}
//覆盖
say(){
super.say()
console.log(this.name, "您好")
}
}
let obj1 = new Student('lkj',18,100)
console.log(obj1)
obj1.say()
23.ajax
// 1.创建XHR new XMLHttpRequest()
var xhr = new XMLHttpRequest()
console.log(xhr)
// 2.配置 open(请求方式,请求地址,是否异步)
// localhost 本机域名 --- 127.0.0.1 本机的ip地址
// baidu.com 百度域名
xhr.open("GET", "http://127.0.0.1:5500/JavaScript%E5%AD%A6%E4%B9%A090-140/32.ajax.json")
// 3.send
xhr.send()
//4.接受数据,注册一个事件
xhr.onload = function(){
if(xhr.status == 200){
document.write(xhr.responseText)
console.log(JSON.parse(xhr.responseText))
}else if(xhr.status == 404){
console.log("没有找到这个页面")
}
}
// xhr.onreadystatechange = function () {
// console.log(xhr.readyState, xhr.responseText)//其实在3的时候数据获取的并不完整
// if (xhr.readyState == 4 && xhr.status == 200) {
// console.log("数据解析完成")
// console.log(xhr.responseText)
// } else if (xhr.readyState == 4 && xhr.status == 404) {
// console.log("没有找到这个页面")
// location.href = "404.txt"
// }
// }
24.ajax案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">获取数据</button>
<ul id="mylist"></ul>
<script>
var btn = document.getElementById("btn")
var mylist = document.getElementById("mylist")
btn.onclick = function () {
var xhr = new XMLHttpRequest()
xhr.open("GET", "http://www.xiongmaoyouxuan.com/api/tabs")
xhr.send()
xhr.onload = function () {
if (xhr.status == 200) {
// console.log(xhr.responseText)
var jsondata = JSON.parse(xhr.responseText)
render(jsondata)
}
}
}
function render(jsondata) {
console.log(jsondata)
console.log(jsondata.data.list)
var html = jsondata.data.list.map(item => `
<li>
<img src="${item.imageUrl}">
<div>${item.name}</div>
</li>
`)
// console.log(html.join(""))
mylist.innerHTML = html.join("")
}
</script>
</body>
</html>
25.同步异步
同步
var xhr = new XMLHttpRequest()
xhr.open("GET","http://127.0.0.1:5500/JavaScript%E5%AD%A6%E4%B9%A090-140/32.ajax.json",true)
// true 表示异步请求
// false 表示同步请求
xhr.send()
xhr.onload = function(){
if(xhr.status == 200){
console.log(xhr.responseText)
}
}
console.log(111111111)
异步
var xhr = new XMLHttpRequest()
xhr.open("GET","http://127.0.0.1:5500/JavaScript%E5%AD%A6%E4%B9%A090-140/32.ajax.json",false)
// true 表示异步请求
// false 表示同步请求
xhr.onload = function(){
if(xhr.status == 200){
console.log(xhr.responseText)
}
}
xhr.send()
console.log(111111111)