첫째, 객체 지향
1.1이 문제를 가리키는
사람을 확인하려면 궁극적 인 함수 호출 예.
인생의이 윈도우 오브젝트 인생에이며, 직접적인 조작으로 작동
인자 클래스 함수 등의 함수 파라미터는 0의 입력으로서 객체의 어레이이고,이를 실행하자 인수 0 , 콘텍스트 arguments 객체 함수이다. 에서 arguments.length도 길이와 기능의 차이를 알고있다.
생성자 1.2
하면이 기능은 "생성자"라고 새로운 오퍼레이터에 의한 함수 호출 (생성자)
생성자 네 단계
빈 객체를 새로 생성
이 널 개체에 바인딩
문이 실행
객체를 반환을
같은 속성 그룹과 함께 밖으로 모든 새로운 객체는 함수가 클래스로 구성 할 수있는 개체의 새 인스턴스 기능 중입니다.
때 생성자 내부의 return 문주의 :
1. 기본 형식이 반환 값이 반환을 무시, 또는 개체가 비밀 생성 돌아 가면
참조 형식이 반환되지 않습니다 원래 개체의 반환 값 인 경우 2.하지만 값의 유형에 대한 참조를 반환
지식의 프로토 타입 체인 :
생성자의 프로토 타입 속성은 __proto__ 속성 인스턴스입니다. 개체가이 속성은 자신의 프로토 타입 객체라는 __ proto__, 자신의 프로토 타입 체인입니다. 프로토 타입 체인은 검색 기능, obj.haha는, OBJ 하하 속성을 가지고 있지 않은 경우, 다음 모양을 가지고 OBJ .__ proto__ 어떤 속성이없고, OBJ.을 찾기 위해 계속 누가 하하 프로토 하하 ... 어떤 속성이 없습니다 .__ proto__ 특성 ...
둘째, 프로토 타입 체인
++ Object.prototype에 프로토 타입 체인에있는 모든 개체의 끝 ++
모든 객체는 프로토 타입 객체 (이 프로토 ), Object.prototype에 마지막 점을, 그러나 Object.prototype에 매우 특별한, 그것은 __proto__의 끝이 null입니다.
JS, 객체는 객체, 함수, 배열 등의 일반 목적은 모든 참조들은 속성 __proto__ 한 값을 개체 입력된다.
심지어, 또한 __proto__가 __proto__ 것을 객체의 샤오밍.
var obj = {}
console.log(obj.__proto__ === Object.prototype); //true
개체 () 생성자가 내장되어 모든 객체는 밖으로 객체 새로운 고려 될 수있다
var obj = new Object();
obj.name = "小明";
obj.age = 12;
console.log(obj)
console.log(obj.__proto__ === Object.prototype);
"{}"__proto__ 객체 점 Object.prototype에는 이후 밖으로 개체의 새로운 기능입니다.
function People(name,age){
this.name = name;
this.age = age;
}
var xiaoming = new People("小明",12);
console.log(xiaoming.__proto__ === People.prototype); //true
console.log(xiaoming.__proto__.__proto__ === Object.prototype); //true
console.log(xiaoming.__proto__.__proto__.__proto__);; //null
요약하면, 샤오밍 프로토 타입 People.prototype은 프로토 타입, 샤오 밍 완벽한 가계도를 가지고 :
Object.prototype에 다른 모든 객체의 유일한 객체 __proto__ 아니라, 기능, 일반 배열과 다른 __proto__가
셋째, 내장 생성자
JS는 또한 "기본 값"래퍼 클래스 "의 기준값」라고도 많은 생성자 내장.
3.1 생성자 형식 기준값
참조 형 생성자 값 : 개체 () 함수 () 배열 () 정규식 ()
3.1.1 객체 () 함수
객체 () 생성자가 내장되어 있습니다, 그것은 빈 객체에 추가 할 수있다 속성, null 객체를 반환, 직접 새가 될 수 있습니다
var obj = new Object();
obj.name = "小明";
obj.age = 12;
console.log(obj)
console.log(obj.__proto__ === Object.prototype);
그것은 동일합니다 :
var obj = {
name:"小明",
age:12
}
3.1.2 함수 () 함수
문자 그대로 모든 기능은의 인스턴스이다
function sum(a,b){
alert(a+b);
}
sum(3,5);
그것은 동일합니다 :
var sum = new Function("a","b","alert(a+b);alert('算完啦!')");
sum(4,5)
제에서 모든 파라미터리스트가 마지막 파라미터는 상기 본체의 함수 인 새로운 함수에서는 매개 변수 문자열 유의한다.
console.log(sum.__proto__ === Function.prototype)
어떤 ++ 기능이 기능은 () 생성자의 예는, 개체 자체 인스턴스 자신을 함수, 함수의 인스턴스입니다. 자신의 기능은 자신을 새. ++
console.log(Object.__proto__ === Function.prototype); //true
console.log(Function.__proto__ === Function.prototype); //true
관계 ++ 기능 및 개체 : ++
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Function.__proto__.__proto__ === Object.prototype); // true
console.log(Function.__proto__.__proto__ === Object.__proto__.__proto__); // true
console.log(Function.__proto__ === Object.__proto__); // true
3.1.3 어레이 () 함수
배열 () 내장 시스템 배열 생성자는, 어떤 배열은 배열 () 새로운 밖으로 새.
var arr = new Array();
arr[0] = 100;
arr[1] = 200;
arr[2] = 300;
console.log(arr);
그것은 동일합니다 :
var arr = [100,200,300];
函数能填参数,表示数组长度,但数组还是空数组:
var arr = new Array(8);
常用的数组方法,都定义在Array.prototype身上。
var arr = [3,3,4,4];
console.log(arr.__proto__ === Array.prototype); //true
console.log(arr.__proto__.__proto__ === Object.prototype); //true
3.1.4 RegExp()函数
任何正则表达式RegExp()函数的实例。
var reg = /\d/g;
//等价于
var reg = new RegExp("d","g");
console.log(reg.__proto__ === RegExp.prototype); //true
console.log(reg.__proto__.__proto__ === Object.prototype); //true
3.2基本类型值“包装类”
【Number()、String()、Boolean()】
基本类型值的构造函数,被称为“包装类”。JS体系为了完整,所以就人为造出了这三个包装类,没有什么用。
3.2.1 Number()函数
用于创建数字对象:
var a = new Number(3);
console.log(a)
console.log(typeof a)
用内置构造函数创建数字的时候,得到一个对象,这对象的原始值属性是:
[[PrimitiveValue]]: 3 //这个属性不可被枚举。
它和字面量创建数字的区别:
var a = new Number(3);
var b = 3;
console.log(a == b); //true
console.log(a === b); //false
用Number()创建的对象,可以参与数学运算:
Number的实例是一个对象,但这个对象一旦参数运算,将变为普通Number类型
var a = new Number(3);
a = a * 3
console.log(a)
console.log(typeof a)
Number()也可以用来把各种值转换为数组(不能转就是NaN),不需要用new调用。
console.log(Number("12")); //12
console.log(Number("12年")); //NaN
console.log(Number("")); //0
console.log(Number(false)); //0
console.log(Number(true)); //1
console.log(Number({})); //NaN
console.log(Number([])); //0
console.log(Number([1,2])); //NaN
任何需要转为数字的隐式转换,实际上就是在调用Number函数。
3.2.2 String()函数
var str = new String("我喜欢你");
console.log(str)
String()也可以用来转换:
console.log(String(123)); //"123"
console.log(String(true)); //"true"
console.log(String([])); //""
console.log(String([1,2,3])); //"1,2,3"
console.log(String(NaN)); //"NaN"
console.log(String({})); //"[Object Object]"
3.2.3 Boolean()函数
不管值是false还是true,都能通过if的验证,都是true。
var b = new Boolean(false);
console.log(b)
console.log(typeof b);
if(b){
alert("真的");
}
3.3内置构造函数之间的关系
就三句话,死记:
1、“{}”对象是被Object new出来的。所以它的__proto__就会指向Object.prototype。
2、任何函数都是Function new出来的实例,所以只要它是函数(构造函数也是函数),它的__proto__就会指向Function.prototype。
3、Function是所有构造函数的妈,它自己也是自己的妈。
小明不是Object new出来的,是People new的,它的__proto__指向People.prototype。
console.log(Object.__proto__.__proto__ === Object.prototype); //true
console.log(Function.__proto__.__proto__ === Object.prototype); //true
console.log(Object.__proto__ === Function.prototype); //true
console.log(Function.__proto__ === Function.prototype); //true
console.log(Array.__proto__ === Function.prototype); //true
console.log(RegExp.__proto__ === Function.prototype); //true
console.log(Number.__proto__ === Function.prototype); //true
console.log(String.__proto__ === Function.prototype); //true
console.log(Boolean.__proto__ === Function.prototype); //true
四、相关的方法、属性、运算符
4.1 hasOwnProperty()方法
返回布尔值(true/false),用来检测某属性、某方法是不是在自己身上。
function People(name){
this.name = name;
}
People.prototype.sayHello = function(){
alert("你好");
}
var xiaoming = new People("小明");
console.log(xiaoming.hasOwnProperty("name")); //true
console.log(xiaoming.hasOwnProperty("sayHello")); //false
console.log(xiaoming.hasOwnProperty("toString")); //false
4.2 in运算符
返回布尔值(true/false),in运算符可以检查某个对象有没有能力调用某属性、某方法,而不管这个属性或方法是否定义在自己身上,还是原型身上。
字符串 in 对象
function People(name){
this.name = name;
}
People.prototype.sayHello = function(){
alert("你好");
}
var xiaoming = new People("小明");
console.log("name" in xiaoming); //true
console.log("sayHello" in xiaoming); //true
console.log("toString" in xiaoming); //true
4.3 constructor属性
每一个函数的prototype对象都有一个constructor属性,指向构造函数。
function People(name){
this.name = name;
}
var xiaoming = new People("小明");
console.log(People.prototype)
console.log(People.prototype.constructor === People); //true
console.log(People.prototype.hasOwnProperty("constructor")); //true
console.log(xiaoming.constructor === People); //true
console.log(xiaoming.hasOwnProperty("constructor")); //false
4.4 instanceof运算符
返回布尔值,用来检查某个对象是不是某个函数的实例
o instanceof F
如果F.prototype在o的原型链上,返回true,否则返回false
function People(name){
this.name = name;
}
var xiaoming = new People("小明");
function Dog(){
}
console.log(xiaoming instanceof People); //true
console.log(xiaoming instanceof Object); //true
console.log(xiaoming instanceof Dog); //false
小题目:
console.log(Object instanceof Object); //true
console.log(Function instanceof Function); //true
console.log(Function instanceof Object); //true
console.log(Number instanceof Function); //true
console.log(Number instanceof Number); //false
我们发现object.prototype是所有对象原型链的终点,所以我敢说任何原型X一定true。
x instanceof Object
// Function的prototype出现在自己的__proto__线上,所以是true
console.log(Function instanceof Function); //true
五、练习题
5.1题目1
function A(){}
function B(){
return new A(); //返回了引用类型值
}
A.prototype = B(); //返回了一个A的实例1
B.prototype = new B();//返回了一个A的实例2
var a = new A(); //返回了一个A的实例,赋给a
var b = new B(); //返回了一个A的实例,赋给b
console.log(a.__proto__ == b.__proto__);
console.log(a instanceof A); //true
console.log(a instanceof B); // false
console.log(b instanceof A); //true
console.log(b instanceof B); //false
5.2题目2
[].constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor === Function //true
六、继承
6.1什么是继承
计算机领域,关注两个类的关系,就是看属性群之间的关系。
比如:人类和狗狗类属性群,难免会有交集,但是不完全重合,此时可以认为两个类没有任何关系。
看看人和学生的属性群:
| 小学生肯定是人,人的属性学生全有,人能做的事情学生都能做。
l 但是反过来,小学生的属性和能力,人不一定有。
“学生”细化了、精分了、更具体了“人”。
“学生”的实例要比“人”的实例少。
“学生”一定是人,但“人”不一定是学生。
术语上,我们称“学生类”继承(extend)“人类”。人类叫“父类(超类)”,学生类叫“子类”。
A继承了B,此时要意识到:
A拥有B的所有属性和方法
A的属性群比B大
A丰富了B,A把B变得更具体,范围更小。
6.2 JavaScript实现继承
JavaScript实现两个类:People类,Student类,要求People类拥有的属性和方法,Student类的实例也要拥有People的属性和方法。Student还能丰富自己类的属性和方法,很简单,只要求巧妙设计原型链。
//人类
function People(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
People.prototype.sayHello = function(){
alert("你好,我是" + this.name);
}
People.prototype.sing = function(){
alert("都拉米发骚啦稀~~~");
}
// 学生类
function Student(name,age,sex,id,banji,socre){
People.apply(this, arguments)
// this.name = name;
// this.age = age;
// this.sex = sex;
this.id = id;
this.banji = banji;
this.socre = socre;
}
//下面这条语句可以实现继承
Student.prototype = new People();
Student.prototype.study = function(){
alert(this.name + "在学习!");
}
var xiaoming = new Student("小明",12,"男",100001,"初三一班", 100)
xiaoming.study();
xiaoming.sayHello();
xiaoming.sing();
注:People.apply(this, arguments)和Student.prototype = new People();要在Student.prototype.*** = function(){}之前
jQuery创始人John Resig写了一个小包,20多行代码,解决了JS继承恶心的问题。
https://johnresig.com/blog/simple-javascript-inheritance/
引包之后,这个包改变我们创建JS类的方式(和jQuery一样改变了写JS的方式)
//人类
var People = Class.extend({
init : function(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
},
sayHello:function(){
alert("你好,我是" + this.name);
},
sing:function(){
alert("都拉米发骚啦希~~~");
}
})
//学生类
var Student = People.extend({
init : function(name,age,sex,id,banji,socre){
this._super(name,age,sex); //继承父类的属性
// this.name = name;
// this.age = age;
// this.sex = sex;
this.id = id;
this.banji = banji;
this.socre = socre;
},
study :function(){
alert(this.name + "在学习!");
}
})
var xiaoming = new Student("小明",12,"男",100001,"初三一班", 100)
console.log(xiaoming)
xiaoming.study();
xiaoming.sing();
七、上升到面向对象
面向对象是一种编程思想,两个字就能概括:自治(自己管理自己),深入理解,就是封装。每个对象个体仅需要管理自己即可。
面向对象初学阶段,当你遇见大量的结构、功能、性质、什么都一样的对象的时候,立刻想到用面向对象技术。
现在要给大家一个思维定式,面向对象的时候怎么编程:
思考初程序中有哪些类,在前期我们的业务仅仅只有一个类,后期类会有多个。
每个类有哪些方法和属性,就是他们自己有什么功能
每个类之间如何通信、交互数据、此时就要用到设计模式,比如中介者模式、发布订阅模式(观察者模式)。
这个类怎么进行单元测试,如果保证自己这个类鲁棒,每个类都鲁棒了,整个程序就鲁棒。
我们之前的编程叫“面向过程”,现在是“面向对象”编程(OO)
7.1面向对象-红绿灯(案例)
문제를 고려, 당신은 페이지를 한 효과를 만들고 싶어 : 100 신호등 신호등을 클릭 노란색으로 변경 붉은 빛, 노란색, 녹색에서 변경 빨간색이되는 녹색 빛을 다시 클릭 다시 클릭 ...
이 세마포어이며, 다음 버튼을 클릭, 신호 변화 0,1,2,0,1,2,0,1,2은 ... 다음 배경 위치 변경 DIV하자, 100 세마포어를 작성해야, 100 개 상자, 100 개 개의 이벤트.
상황이 페이지가 신호등입니다에 표시되며, 클래스로 설계 신호등을 할 수 그들은 동일한 모양, 자연, 기능을 가지고있다.
① 국가 수량 ②DOM 요소 : 어떤 각 클래스 것은 책임이 있습니다.
JS 각 객체 두 속성 중 하나 개의 속성 상태를 가지며, 다른 하나는 DOM 오브젝트는
간단히 말해, DOM은 이제 JS 객체의 속성이 될 객체.
这个类有哪些属性?
DOM属性
颜色属性
哪些方法?
初始化方法 init()
换颜色方法 changeToColor()
绑定事件方法 bindEvent()
첫 번째 단계 : DOM 구조 및 CSS 스타일이 빛을 볼 수 있었다 div 요소를 넣어해야합니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style type="text/css">
*{ margin: 0; padding: 0;}
div.honglvdeng{
position: relative;
width: 140px;
height: 328px;
background: url(./images/honglvdeng.jpg);
}
</style>
</head>
<body>
<div id="box">
<div class="honglvdeng"></div>
</div>
</body>
</html>
//第二步:创建红绿灯类
//new Honglvdeng()时,会执行构造函数中的语句
//所以在构造函数中创建一个DOM对象,然后让它上树
function Honglvdeng(){
//每一个类中有两个属性:状态量、DOM
this.dom = null;
//状态属性
this.state = 0;
//初始化方法
this.init();
//事件监听方法
this.bindEvent();
}
//为了程序美观,整洁,好更改和可插拔性高,方便维护,将DOM和上树语句都写在初始化方法中
Honglvdeng.prototype.init = function(){
//创建DOM
this.dom = document.createElement('div');
//给DOM添加类名
this.dom.className = 'honglvdeng';
//上树
document.getElementById("box").appendChild(this.dom);
}
//第三步:添加事件监听
Honglvdeng.prototype.bindEvent = function(){
//备份this,因为事件监听里面的this表示dom元素本身
var self = this;
this.dom.onmouseenter = function(){
// 改变信号量
// self.state++;
// if(self.state > 2) self.state = 0
//判断简写
self.state = ++self.state % 3;
self.dom.style.backgroundPositionX = -155 * self.state +'px';
}
}
//第四步:实例化100个红绿灯
var count = 100;
while(count--){
new Honglvdeng();
}
제 재현 mufengsm