##js [ECMAScrip+DOM+BOM] 1.js参考 2.es5参考3.实例与对象的区别4.对象与json的区别5.创建对象的若干种方式 6.实例属性类属性实力方法类方法
###js:一种动态类型、弱类型、基于原型的客户端脚本语言,用来给HTML网页增加动态功能。
动态: 在运行时确定数据类型。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。
弱类: 计算时可以不同类型之间对使用者透明地隐式转换,即使类型不正确,也能通过隐式转换来得到正确的类型。
原型(prototype): 自定义的对象继承object对象(作为模版),object将自身的属性共享给新对象,模版对象称为原型。
这样新对象实例化后不但可以享有自己创建时和运行时定义的属性,而且可以享有原型对象的属性。
###ECMAScript(核心)
###BOM
###DOM
1.面向对象(oop)对象参考 es6和es6面向对象区别
面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装、继承、多态(、聚集的特性!
封装 - 把相关的信息(无论数据或方法)存储在对象中的能力
继承 - 由另一个类(或多个类)得来类的属性和方法的能力
多态 - 编写能以多种方法运行的函数或方法的能力
聚集 - 把一个对象存储在另一个对象内的能力
但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义JS中对象:无序属性的集合,其属性可以包含基本值、对象或者函数。可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)。
1)js中一切皆对象:如字符串、数值、数组、函数...;
js允许自定义类和构建对象(对象构造器[即函数],然后再new一下就ok);
例:
#es5的写法,es6有了class关键字
function Person(firstname,lastname,age,eyecolor){#Person自定义类
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;
nation='china' #类属性
}
var myFather=new Person("Bill","Gates",56,"blue");#构建对象
对象只是带有属性和方法的特殊数据类型;
基本数据类型(对象):number string boolean null object undefined
基本对象类型(typeof ):number string boolean object(object、null) fuction undefined
实例的typeof是object,类(本质是函数,模拟类)的typeof是function
2)实例与对象以及json的与的区别(实例都是对象,对象不一定是实例)【参见链接3,4】
实例是类的具象化产品
而对象是一个具有多种属性的内容结构
理解:
动物 --- 对象
一只狗 --- 实例 (狗具备动物的特征,并且是唯一的,具体的!)
例:
var person = new Object(); --实例
var person = {};--采用对象字面量的方式生成的person,然而它内部没有调用new Object(),而是采用JSON的初始化方式。
json可以点属性,对象也可以点属性。json本质也是对象,一切皆对象。json的key是字符串,json的value可以是指向对象的。
对于function函数:
函数实际上就是对象,每个函数都是Function类型的实例,由于函数是对象,
因此函数名也是指向函数对象的一个指针,并不会和函数绑定
3)创建对象的若干种方式(工厂模式)和单例【参见链接5】
1.工厂模式:将创建对象的过程抽象为一个函数,用函数封装以特定接口创建对象的细节
缺点:工厂模式虽然可以创建多个相似的对象,但却不能解决对象标识的问题,即怎样知道一个对象的类型【构造函数解决了这个问题】
例1:function createStudent(name,sex,grade){
var o = new Object();
o.name = name;
o.sex = sex;
o.grade = grade;
o.sayName = function(){
console.log(this.name);
}
return o;
}
var s1 = createStudent('Claiyre','famale',1);
例2:function Human(name,age) {
this.name=name;
this.age=age;
this.show=show;
nation='china';
// return{
// "getNation":function () {
// return nation
// },
// "setNation":function (val) {
// nation=val;
// },
// type:'animal' //全局类属性
// }
}
2.构造函数模式:在JavaScript中没有类的概念,故不必显式声明某个类,直接创建构造函数即可,类的方法和属性在构造函数中(或原型对象上)处理
缺点:每个方法都要在每个实例上创建一遍。(也就是说通过构造函数实例化的多个对象的方法,是多个不同的方法,但它们内部的代码以及实现的功能是相同的,这就造成了一定的资源浪费。)
【这个问题可以用原型模式来解决。】
function Student(name,sex,grade){
this.name = name;
this.sex = sex;
this.grade = grade;
this.sayName = function(){
console.log(this.name);
}
}
var s2 = new Student('孙悟空','male',2);
调用构造函数创建对象经过了以下几个过程:
创建一个新对象
将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
执行构造函数中的代码
返回新对象(不需要显式返回)
与工厂模式相比,用构造模式创建对象有以下几点不同:
没有显示地创建对象
直接将属性和方法赋给this对象
没有return语句
3.原型模式:js中每个函数都有prototype属性,它是一个指针,指向prototype原型对象,原型对象包含了所有对象共享的属性和方法。此外原型对象还有一个constructor属性,指向创建对象的构造方法
function Student_1(){
}
Student_1.prototype.name = 'Claiyre';
Student_1.prototype.sex = 'female';
Student_1.prototype.class = 5;
Student_1.prototype.sayName = function (){
console.log(this.name);
}
var s5 = new Student_1();
s5.sayName(); //Claiyre
var s6 = new Student_1();
s6.sayName(); //Claiyre
4.单例(类只有一个对象):
var person = {
name : 'My name',
age : 18,
getName : function(){
return this.name;
}
}
4)为实例动态增加删除属性
delete 类名.属性名 // 或者将属性值设置为undefined
对象.属性=
5)writable、enumerable和configurable等数据属性
writable : 布尔值,设置属性的值是否可以被重写,false只读
enumerable : 布尔值,设置属性是否可以被枚举,false(for in时不能被枚举)
configurable : 布尔值,设置属性是否可以被删除,默认属性值为false(不能被删除)
????get: 在读取时属性是调用的函数,不设置get方法是默认underfind
????Set: 在写入取时属性是调用的函数,不设置set方法时默认underfind
6)实例属性,类属性,全局类属性【参见1)和链接6】;实例方法,类方法
实例属性:this.属性名来访问,(也叫共有属性)[类方法中有this.属性名=属性变量]
类属性:类名.属性名来访问[构建类属性时,在函数外,类名.属性名=‘’]
prototype:原型对象共有属性
全局类属性:工厂模式中return的属性【实例名.该属性可以】
7)prototype原型(是object类的属性其属性值指向对象,其中包含constructor)[每一个函数对象都有一个prototype属性,但是普通对象是没有的]
1. protopye与constructor与__proto__
prototype属性属于function(从object里继承过来的),prototype属性指向prototype原型对象,该对象包含constructor属性(construct属性指向构造方法,相当于python中的__init__)属性
2. 为节约内存共有属性和方法应挂载在prototype
3. 原型继承链:实例属性-->父类的prototype-->object的prototype-->都没有返回undefined
8)call和apply实现不相关实例属性和方法继承(本质是借用并非继承)[call,第一个参数是替换对象,其后都是数据传给类方法;apply第一个是替换对象,其后是数组]
function Teacher() {
this.name='teacher'
}
Teacher.prototype.teach=function () {
console.log('i can teach student');
}
function Student() {
this.name='student'
}
Student.prototype.study=function () {
console.log('i am '+this.name+'i can study it');
}
var t=new Teacher();
var s=new Student();
s.study()
s.study.call(t)
9)伪数组转化为真数组
function func(a,b,c,d) {
console.log(arguments)
// var args=[];
// for(var i of arguments){
// args.push(i)
// }
// arguments.slice(0)
// var args=[].slice.call(arguments,0);
// var args=(new Array).slice.call(arguments,0);
var args=Array.prototype.slice.call(arguments,0);
console.log(args.reverse());
}
// var arr=[1,3,4,2];
func(1,2,3,4);
10)instanceof 判断对象的父类,返回true/false:alert(s1 instanceof Student)
constructor:同一类构建出来的两个对象的construor是一致的:alert(s1.constructor===s2.constructor)
11)use strict
###2.es6中的扩展es5基本语法参考!!!es6
会默认采用严格模式
1)变量声明 用let或const代替var
[在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围]
let:先声明再使用(不会声明提升);不能重复声明;作用域(函数内部)是函数块级元素
const:常量(只读)
2)箭头的使用(箭头函数[相当于lambda表达式]可以替换函数表达式,但是不能替换函数声明)
注意:如果你在箭头函数中使用了this,那么该this一定就是外层的this。
也正是因为箭头函数中没有this,因此我们也就无从谈起用call/apply/bind来改变this指向
例1:
// es5
var fn = function(a, b) {
return a + b;
}
// es6 箭头函数写法,当函数直接被return时,可以省略函数体的括号
const fn = (a, b) => a + b;
// es5
var foo = function() {
var a = 20;
var b = 30;
return a + b;
}
// es6
const foo = () => {
const a = 20;
const b = 30;
return a + b;
}
例2:在ES6中,会默认采用严格模式,因此this也不会自动指向window对象了,而箭头函数本身并没有this,因此this就只能是undefined这种情况,如果还想用this,就不要用使用箭头函数的写法。【参考链接】
3)模板字符串`${}`
4)解析结构
5)函数默认参数
6)展开运算符
7)对象字面量与class
8)promise
9)extends
10)模块modules