一堪侯、認識對象
如何判斷是否是對象? 能添加屬性值荔仁。
- 狹義對象
所謂狹義對象就是{}形式定義的對象伍宦,它是一組屬性的無序集合。對象是鍵值對乏梁,既有值次洼,也有語義。
var obj = {
name:"小明",
age:12,
sex:"男",
hobby:["游戲","編程"]
}
對象就是一組值和值得語義的封裝
- 廣義對象
除了可以有屬性還有其他東西掌呜,有一個dom元素在頁面上
var o = document.getElementById("box");
alter(typeof o);// object
o.sex = 22;
o.name = "小紅";
系統(tǒng)內(nèi)置的所有引用類型值都是對象滓玖,都能添加自定義屬性坪哄。
- function 函數(shù)
- array 數(shù)組
- regexp 正則表達式
- DOM 元素
- window质蕉、document、Math翩肌、Date
- Number模暗、String 等內(nèi)置包裝構(gòu)造函數(shù)得到的值
- 什么不是對象
var a = 100;
a.age = 12;
alert(a.age); //undefined
var s = "哈哈";
s.age = 12;
alert(a.age); //undefined
基本類型值,字面量不是對象
number,string,boolean,undefined,null
二念祭、對象和 JSON 的區(qū)別
JSON 就是 javascript object notation,JS對象表示法兑宇,是JS對象的嚴格子集。
JSON要求所有的鍵必須加雙引號粱坤,而JS對象實際上不要求加雙引號隶糕。
// JSON格式
var obj1 = {
"name": "小明",
"age": 12,
"sex": "男"
}
//js對象 不嚴格要求雙引號
var obj2 = {
name: "小明",
age: 12,
sex: "男",
}
但是有一種情況js對象的鍵必須加引號瓷产!
就是不符合標識符命名規(guī)范的鍵,必須加引號枚驻,否則報錯濒旦。
//合法
var obj = {
$ : 12,
_ : 13 ,
_$0_0$_: 14
}
//不合法,需加雙引號再登,取值時需 obj["2016"] 中括號+引號調(diào)用
// 命名規(guī)則如下
//1.由字母尔邓、數(shù)字、$锉矢、_組成
//2.以字母梯嗽、$、_開頭
//3.不可以使用保留字9了稹5平凇!
var obj = {
"-":12,
"@@@":13,
"2016":12,
"哈哈":15
}
三绵估、對象的方法
如果一個對象的屬性值是一個函數(shù)显晶,我們稱這個屬性叫做這個對象的方法(methods)
var obj = {
name: "小明",
age: 12,
sex: "男",
sayHello: function(){
alert("你好");
}
}
四、函數(shù)的上下文(context)
- 函數(shù)上下文是什么壹士?
函數(shù)的上下文其實就是函數(shù)里this的指向磷雇。
- 函數(shù)this指向誰?躏救,或者說函數(shù)上下文是誰唯笙?
函數(shù)的上下文是誰?盒使,取決于函數(shù)如何調(diào)用崩掘,而不是函數(shù)如何定義(定義的位置)少办。
函數(shù)的上下文是函數(shù)的調(diào)用時表現(xiàn)的性質(zhì)苞慢,不是函數(shù)定義的時候?qū)懰赖男再|(zhì)。(換句話說英妓,就是函數(shù)不調(diào)用時挽放,無法判斷函數(shù)上下文是誰)
var obj = {
name: "小明",
age: 12,
sex: "男",
sayHello: function(){
alert("你好"+this.name+",年齡是"+this.age+"歲");
}
}
obj.sayHello();
var fn = obj.sayHello;
fn();
var name = "小紅";
var age = 22;
fn();
- 函數(shù)的上下文六大規(guī)律
規(guī)律1:函數(shù)直接圓括號調(diào)用,函數(shù)的上下文是window對象
(所有的全局變量都是window對象的屬性蔓纠,而函數(shù)內(nèi)部的變量是局部變量辑畦,不是window的屬性,也不是這個函數(shù)的屬性)
//例子1
function fn(){
var a = 666;
alert(this.a);
}
var a = 777;
fn();
//例子2
var a = 777;
function fn(){
var a=666;
var ff = function(){
alert(this.a);
}
ff();
}
fn();
規(guī)律2:函數(shù)如果作為一個對象的屬性腿倚,被對象打點調(diào)用纯出,那么函數(shù)的上下文就是這個對象
var obj = {
name: "小明",
age: 12,
sex: "男",
sayHello: function(){
alert("你好"+this.name+",年齡是"+this.age+"歲");
}
}
obj.sayHello();
規(guī)律3:函數(shù)是事件處理函數(shù),函數(shù)的上下文就是觸發(fā)此事件的對象
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
.box{
width: 100px;
height: 100px;
background: black;
margin: 10px;
}
</style>
</head>
<body>
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>
<div class="box" id="box3"></div>
<script src="js/jquery-3.2.1.js"type="text/javascript" ></script>
<script>
function fn (){
this.style.background = "red";
}
var box1 = document.getElementById("box1");
var box2 =document.getElementById("box2");
var box3 =document.getElementById("box3");
box1.onclick = fn;
box2.onclick = fn;
box3.onclick = fn;
</script>
</body>
</html>
規(guī)律4:定時器調(diào)用函數(shù),函數(shù)的上下文是window對象
//例1
function fn(){
alert(this.aa);
}
var aa = 66666;
setInterval(fn,2000);
//例2
function fn(){
alert(this.aa);
}
var aa = 66666;
setInterval(function(){
fn(); //這種可看為規(guī)律1暂筝,結(jié)果一樣指向window
},2000);
//例3
document.getElementById("box1").onclick = function(){
setInterval(function(){
this.style.background = "red";
},1000);
};
//正例
document.getElementById("box1").onclick = function(){
var self = this;
setInterval(function(){
self.style.background = "red";
},1000);
};
規(guī)律5:數(shù)組中存放的函數(shù)箩言,被數(shù)組通過索引直接圓括號調(diào)用,那么這個函數(shù)的上下文就是這個數(shù)組
function fn(){
console.log(this);
alert(this[2]);
}
var arr = [fn,"EZ","蓋倫"];
arr[0]();
五焕襟、構(gòu)造函數(shù)
- new運算符
function Person(){
alert("aaa");
}
new Person(); //彈出aaa
通過上述例子我們可以看出new 運算符會調(diào)用函數(shù)分扎。
function Person(){
this.name = "小明";
this.age = 12;
}
var obj = new Person();
alert(obj.name);//彈出小明
通過上述例子可以看出 new 運算符調(diào)用函數(shù)會執(zhí)行哪些操作?
- 新建一個空對象{}
- 將函數(shù)的this指向這個空數(shù)組
- 執(zhí)行函數(shù)體內(nèi)容
- 執(zhí)行完畢后胧洒,retrun 返回剛才創(chuàng)建的對象
function Person(name,age){
this.name = name;
this.age = age;
}
var xiaoming = new Person("小明",12);
var xiaohong = new Person("小紅",22);
console.log(xiaoming);
console.log(xiaohong);
我們改造一下畏吓,發(fā)現(xiàn)JS的這種構(gòu)造函數(shù),很像JAVA里的類對象了卫漫。
我們可以認為Person是一個 “類”菲饼,而 xiaoming,xiaohong就是這個類的 “實例”。
六列赎、原型鏈
_proto_ 是神器宏悦,具有原型鏈查找功能,當在xiaoming實例身上找不到某屬性的時候包吝,會沿著proto去原型對象上查找是否有這個屬性饼煞。
//例
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype = {
teacher : "流浪法師",
zhishang: 180
}
var xiaoming = new Person("小明",12);
var xiaohong = new Person("小紅",22);
alert(xiaoming.teacher);
alert(xiaohong.teacher);
可以看一下jQuery 的源碼,如何運用原型鏈诗越,做一些巧妙的設(shè)計砖瞧。
最經(jīng)典的就是jQuery的無new構(gòu)造,不需要繁瑣的new $("input") ,只需要$("input")即可獲得實例嚷狞。
(function(window, undefined) {
var
// ...
jQuery = function(selector, context) {
// The jQuery object is actually just the init constructor 'enhanced'
// 看這里块促,實例化方法 jQuery() 實際上是調(diào)用了其拓展的原型方法 jQuery.fn.init
return new jQuery.fn.init(selector, context, rootjQuery);
},
// jQuery.prototype 即是 jQuery 的原型,掛載在上面的方法床未,即可讓所有生成的 jQuery 對象使用
jQuery.fn = jQuery.prototype = {
// 實例化化方法竭翠,這個方法可以稱作 jQuery 對象構(gòu)造器
init: function(selector, context, rootjQuery) {
// ...
}
}
// 這一句很關(guān)鍵,也很繞
// jQuery 沒有使用 new 運算符將 jQuery 實例化薇搁,而是直接調(diào)用其函數(shù)
// 要實現(xiàn)這樣,那么 jQuery 就要看成一個類斋扰,且返回一個正確的實例
// 且實例還要能正確訪問 jQuery 類原型上的屬性與方法
// jQuery 的方式是通過原型傳遞解決問題,把 jQuery 的原型傳遞給jQuery.prototype.init.prototype
// 所以通過這個方法生成的實例 this 所指向的仍然是 jQuery.fn啃洋,所以能正確訪問 jQuery 類原型上的屬性與方法
jQuery.fn.init.prototype = jQuery.fn;
})(window);