JavaScript面向对象编程

创建类:class name{
	//class body
}
创建实例:var xx=new name()
注意:类必须使用new实例化对象

类constructor构造函数:
constructor()方法是类的构造函数,用于传递参数,返回实例对象,通过  new 命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor()

例:class Star{//class创建一个明星类
	constructor(uname,age){
			this.uname=uname;//this.指向创建的实例对象
			this.age=age
		}
		sing(){
			console.log('我唱歌')
		}
	}
	//利用类创建对象 new
	var ldh = new Star('刘德华',18);
	//此时ldh.uname='刘德华'
	var zxy=new Star('张学友'.20)
	ldh.sing();
	zxy.sing();
注意:1.类里面所有的函数不需要加function
2.多个函数直接不需要添加逗号分隔

类的继承:
class 子类 extends 父类
例:
class Father{
	constructor(){
		
	}
	money(){
		console.log(100);
	}
}
class son extends Father{
		
	}	
var son=new Son();
son.money;

如果父类中的函数有this,则this指向的是父类,儿子继承该this之后也指向的是父类,此时则需要使用super关键字,它用于访问和调用对象父类上的构造函数和普通函数
class Father{
	constructor(x,y){
		this.x=x;
		this.y=y;
	}
	sum(){
		console.log(this.x+this.y);
	}
}
class Son extends Father{
	construct(x,y){
		//在子类的构造函数当中调用父类的构造函数,并且传入参数给父类的this.x和this.y,就能使用sum函数,儿子继承该this之后也指向的是父类
		super(x,y);
	}
}
var son=new Son(1,2);
son.sum();
如果子类和父类有相同名字的函数,继承之后再调用还是子类函数的功能,super.函数名()可以调用父类的这个函数
如果父类和子类都有this,子类继承时super()必须在子类this之前调用

注意点:
1.在es6中类没有变量提升,所以必须先定义类,才能通过实例化对象
2.类里面的共有属性和方法一定要加this使用。(在非构造函数中使用传入构造函数的形式参数需要在前加this3.constructor 里面的this指向的是创建的实例对象,其他的函数中this如果由实例对象调用则指向该实例对象,如果由按钮等调用则指向按钮。定义一个全局变量再构造函数中把this赋值给该全局变量,在函数的每一个地方都可以使用该变量作为实例对象

获取元素需要在constructor当中,并且每个变量之前要加this

把字符串格式元素添加到父元素中:
element.insertAdjacentHTML(position,text)
position是相对于元素的位置,并且必须是以下字符串之一:
beforebegin:元素自身的前面
afterbegin:插入元素内部的第一个子节点之前
beforeend:插入元素内部的最后一个子节点之后
afterend:元素自身的后面
text:是要被解析为HTML的字符串
appendChild不支持追加字符串的子元素,insertAdjacentHTML支持追加字符串的元素

Math.random()可以生成一个随机数
在页面当中新建元素之后要重新获取一遍元素

事件对象阻止冒泡:e.stopPropagation()
移除元素:element.remove()
条件1 && 条件2 :条件1为真执行条件2,条件1为假则不执行,类似if
选中文本框当中的文字:input.select()
手动调用元素的点击或焦点等事件不需要加on

鼠标双击事件:ondlclick
如果双击文字,会默认选定文字,此时需要双击禁止选中文字:window.getSelection?window.getSelection().removeAllRanges():document.selection.empty()

在es6之前对象不是用基于类创建的,而是用构造函数的特殊函数来定义对象和他们的特征
创建对象的方法:
1.利用new Objiec()创建对象
var obj1=new Object()
2.利用对象字面量创建对象
var obj2={}
3.利用构造函数创建对象
function Star(uname,age){
	this.uname=name;
	this.age=age;
	this.sing=function(){
		aler(1);
	}
}
var ldh=new Star('刘德华'18);
var zxy=new Star('张学友'19);
ldh.sing()
zxy.sing()
构造函数中的属性和方法称为成员,成员可以添加
1.实例成员:
实例成员就是构造函数内部通过this添加的成员,uname age sing
实例成员只能通过实例化对象来访问,不可以通过构造函数来访问,例:ldh.age为真,Star.age为假
2.静态成员:
静态成员在构造函数本身上添加的成员
例如:Star.sex='男'
静态成员只能通过构造函数来访问,不能通过对象访问

普通的构造函数当中存在浪费内存的问题,但是构造函数通过原型分配的函数是所有对象所共享的
每一个构造函数都有一个prototype属性,指向另一个对象,这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
我们可以把那些不变的方法(函数),直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法,公共属性定义到构造函数当中
例:function Star(uname,age){
	this.uname=name;
	this.age=age;
	Star.prototype.sing=function(){
		aler(1);
	}
}
var ldh=new Star('刘德华'18);
var zxy=new Star('张学友'19);
ldh.sing()
zxy.sing()

对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有_proto_原型的存在。ldh.__proto === Star.prototype

对象原型(__proto__)和构造函数(原型对象prototype)原型对象里面都有一个constructor属性,constructor我们称为构造函数,因为它指回构造函数本身。
constructor主要用于记录该对象引用哪个构造函数,它可以让原型对象重新指向原来的构造函数

如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动利用constructor指回原来的构造函数

构造函数、实例、原型对象三者之间的关系:
Star构造函数可以通过Star.prototype指向Star原型对象prototype,Star原型对象prototype可以通过Star.prototype.constructor指回Star构造函数。Star构造函数可以创建一个ldh对象实例,ldh对象实例可以通过ldh.__proto__指向Star原型对象,ldh对象实例可以通过ldh.__proto__.constructor指向Star构造函数

this指向:
1.在构造函数中,里面this指向的是对象实例ldh
2.原型对象函数里面的this指向我的是实例对象ldh

可以通过原型对象,对原来的内置对象进行扩展自定义的方法。
例:Array.prototype.sum=function(){
	var sum=90;
	for(i=0;i<this.length;i++){
		sum+=this[i];
	}
	return sum;
}
var arr=[1,2,3];
console.log(arr.sum());
var arr1=new Array(11,22,33);
console.log(arr1.sum());
注意:数组和字符串内置对象不能给原型对象覆盖操作Array.prototype={},只能是Array.prototype.xxx=function(){}的方式

call方法:
1.call()可以调用函数
例:function fn(){
	console.log('11');
	console.log(this);
	console.log(x+y);
}
fn.call()
2.call()可以改变这个函数的this指向,此时函数的this指向o
var o={
	name:'andy';
}
fn.call(o,1,2);

借用父构造函数继承属性:
1.父构造函数
function Father(uname,age){
	//this指向父构造函数的对象实例
	this.uname=uname;
	this.age=age;
}
Father.prototype.money=function(){
	console.log(100);
}
2.子构造函数
function Son(uname,age,score){
	//this指向子构造函数的对象实例
	Father.call(this,uname,age);
	this.score=score;
}

//Son.prototype=Father.prototype;//这样直接赋值如果修改了子原型对象,父原型对象也会修改
Son.prototype=new Father();
//如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的构造函数
Son.prototype.constructor=Son;
//这个是子构造函数专门的方法
Son.prototype.exam=function(){
	console.log('孩子要考试');
}
var son=new Son('刘德华',18,100);
console.log(son);

数组方法:
迭代(遍历)方法:forEach()、map()、filter()、some()、every();

array.forEach(function(currentValue,index,arr))
currentValue:数组当前项的值
index:数组当前项的索引
arr:数组对象本身
例:var arr=[1,2,3]
var som=0;
arr.forEach(function(value,index,array){
	console.log('每个数组元素'+value);
	console.log('每个数组元素的索引号'+index);
	console.log('数组本身'+array);
	sum+=value;
})
console.log(sum);

array.filter(function(currentValue,index,arr))
filer()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,主要用于筛选数组
注意它直接返回一个新数组
currentValue:数组当前项的值
index:数组当前项我的索引
arr:数组对象本身
例:var arr=[12,66,4,88];
var newArr=arr.filter(function(value,index){
	return value >=20;
})
console.log(newArr);

array.some(function(current,index,arr))
some()方法用于检测数组中元素是否满足指定条件(效率高于其他遍历方法)
注意它返回值是布尔值,如果查找到这个元素,就返回true,否则就返回false
如果找到第一个满足条件的元素则终止循环,不在继续查找,满足条件return true会终止迭代

字符串方法:
trim()方法会从一个字符串的两端删除空白字符 
str.trim()
trim()方法并不影响原字符串本身,它返回得到的是一个新的字符串

对象方法:
1.Object.keys()用于获取对象自身所有的属性
效果类似for...in遍历
返回一个由属性名组成的数组
2.Object.defineProperty()定义对象中新属性或修改原有的属性,有的话就用value修改,没有就增加
Object.defineProperty(obj,prop,descriptor)
obj:必须。目标对象
prop:必须。需定义或修改的属性的名字
Object.defineProperty()第三个参数descriptor说明:以对象形式{}书写
value:设置书写的值,默认为undefined
writable:值是否可以被修改。true|false 默认为false,不允许修改
enumerable:目标属性是否可以被枚举(遍历)。true|false 默认为false
configurable:目标属性是否可以被删除或是否可以再次修改特性true|false 默认为false

利用new Function('参数1''参数2','函数体')来定义函数
var f=new Function('a','b','console.log(a+b)');
f(1,2);
所有函数都是Function的实例对象,都有__proto__属性
a instanceof Object:可以判断前者是否属于后者

函数的调用方式:
1.普通函数:
function() fn(){
	console.log('普通函数的this'+this);
}
fn();//fn.call()
this指向window
2.对象的方法
var o={
	sayHi:function(){
		console.log('1')
	}
}
o.sayHi();
此时this指向o
3.构造函数
function Star(){}
var ldh= new Star();
this指向实例对象,原型对象中的this也指向实例对象
4.绑定事件函数中的this指向函数的调用者
5.定时器中函数的this指向window
6.立即执行函数的this指向winwindow

改变函数内部this指向:bind()  call()  apply()
call()的主要作用可以实现继承
1.可以调用函数
2.可以改变函数内的this指向
例:
function Father(uname,age,sex){
	this.uname=uname;
	this.age=age;
	this.sex=sex;
}
function Son(uname,age,sex){
	Father.call(this,uname,age,sex);
}
var son=new Son('刘德华',18,'男');

fun.apply(thisArg,[argsArray])
thisArg:在fun函数运行时指定的this值
argsArray:传递的值,必须包含在数组里面
返回值就是函数的返回值,因为它就是调用函数
例:
var o={
	name:'andy';
};
function fn(){
	console.log(this);
	console.log(arr);
};
fn.apply(o,[1])
比较数组中的最大值:
var arr=[1,66,3,99,4];
var max=Math.max.apply(null,arr);
console.log(max);

bind():方法不会调用函数,但是能改变函数内部this指向
fun.bind(thisArg,arg1,arg2,..)
thisArg:在fun函数运行时指定的this值
agr1,agr2:传递的其他参数
返回由指定的this值和初始化参数改造的原函数拷贝,是一个新的函数
var o={
	name:'andy';
};
function() fn(a,b){
	console.log(this);
	console.log(a+b);
};
var f=fn.bind(o,1,2);
f();

为整个脚本开启严格模式
script
'use strict';
/script

为某个函数开启严格模式
script
	//只给fn开启严格模式
	function fn(){
		'use strict';
	}
/script

在非严格模式下的函数中this指向window对象,在严格模式下的函数中this指向undefined
在非严格模式下的构造函数不加new也可以调用,当普通函数,this指向全局对象,严格模式下构造函数不加new调用this会报错
new实例化的构造函数指向创建的实例对象

高阶函数是对其他函数进行操作的函数,它接受函数作为参数或将函数作为返回值输出


闭包:指有权访问另一个函数作用域中变量的函数
主要作用:延伸了变量的作用范围
例:function fn(){
	var num=10;
	return function(){
		console.log(num);
	};
}
var f=fn();
f();
从fn外面的作用域可以访问fn内部的局部变量
例:利用闭包的方式得到当前的小li的索引号
for(var i=0;i<lis.length;i++)
//利用for循环创建了4个立即执行函数
{
	(function(i){
		lis[i].onclick=function(){
			sonsole.log(i);
		}
	})(i);
}

例:var car=(function(){
	var start =13;
	var total=0;
	return {
		price:function(){
			
		}
		yd:function(){
			
		}
	}
})
console.log(car.yd);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值