JavaScript學習記錄十四
建立物件三種方式: //1 字面量的方式 //2 呼叫系統的建構函式 //3 自定義建構函式方式
* 1.開闢空間儲存物件 * 2.把this設定為當前的物件 * 3.設定屬性和方法的值 * 4.把this物件返回
//例項物件 var per1={ name:"卡卡西", age:20, sex:"男", eat:function () { console.log("吃臭豆腐"); }, readBook:function () { console.log("親熱天堂"); } }; //呼叫系統的建構函式 var per2=new Object(); per2.name="大蛇丸"; per2.age=30; per2.sex="男"; per2.eat=function () { console.log("吃榴蓮"); }; //自定義建構函式 function Person(name,age,sex) { this.name=name; this.age=age; this.sex=sex; this.play=function () { console.log("天天打遊戲"); }; } var per=new Person("雛田",18,"女");
工廠模式常見物件
* 共同點:都是函式,都可以建立物件,都可以傳入引數 * * 工廠模式: * 函式名是小寫 * 有new, * 有返回值 * new之後的物件是當前的物件 * 直接呼叫函式就可以建立物件 * * 自定義建構函式: * 函式名是大寫(首字母) * 沒有new * 沒有返回值 * this是當前的物件 * 通過new的方式來建立物件
function createObject(name,age) { var obj=new Object(); obj.name=name; obj.age=age; obj.sayHi=function () { console.log("您好"); }; return obj; } function Person(name,age) { this.name=name; this.age=age; this.sayHi=function () { console.log("您好"); }; } var per1=new Person("小紅",20); var per2=createObject("小明",20);
例項物件和建構函式之間的關係
* 例項物件和建構函式之間的關係: * 1. 例項物件是通過建構函式來建立的---建立的過程叫例項化 * 2.如何判斷物件是不是這個資料型別? * 1) 通過構造器的方式 例項物件.構造器==建構函式名字 * 2) 物件 instanceof 建構函式名字 * 儘可能的使用第二種方式來識別,為什麼?原型講完再說
通過建構函式建立物件的問題
function myEat() { console.log("吃大榴蓮"); } var myEat=10; function Person(name,age) { this.name=name; this.age=age; this.eat=myEat; } var per1=new Person("小白",20); var per2=new Person("小黑",30); console.dir(per1); console.dir(per2); console.log(per1.eat==per2.eat);true →10 //通過原型來解決---------資料共享,節省記憶體空間,作用之一
解決:通過原型來新增方法解決資料共享的問題
function Person(name,age) {
this.name=name;
this.age=age;
}
//通過原型來新增方法,解決資料共享,節省記憶體空間
Person.prototype.eat=function () {
console.log("吃冷盤");
};
var p1=new Person("小明",20);
var p2=new Person("小紅",30);
console.log(p1.eat==p2.eat);//true
console.dir(p1);
console.dir(p2);
原型 * 例項物件中有__proto__這個屬性,叫原型,也是一個物件,這個屬性是給瀏覽器使用,不是標準的屬性----->__proto__----->可以叫原型物件 * 建構函式中有prototype這個屬性,叫原型,也是一個物件,這個屬性是給程式設計師使用,是標準的屬性------>prototype--->可以叫原型物件 * * 例項物件的__proto__和建構函式中的prototype相等--->true * 又因為例項物件是通過建構函式來建立的,建構函式中有原型物件prototype * 例項物件的__proto__指向了建構函式的原型物件prototype
這一段和上面那一段接著,為原型的設定和使用
console.dir(p1);
console.dir(p2);
console.dir(Person);
p1.__proto__.eat();//吃冷盤
console.log(p1.__proto__==Person.prototype);//true
面向過程的程式設計思想和麵向物件的程式設計思想
function ChangeStyle(btnObj, dvObj, json) {
this.btnObj = btnObj;
this.dvObj = dvObj;
this.json = json;
}
ChangeStyle.prototype.init = function () {
//點選按鈕,改變div多個樣式屬性值
var that = this;
this.btnObj.onclick = function () {//按鈕
for (var key in that.json) {
that.dvObj.style[key] = that.json[key];
}
};
};
//例項化物件
var json = {"width": "500px", "height": "800px", "backgroundColor": "blue", "opacity": "0.2"};
var cs = new ChangeStyle(my$("btn"), my$("dv"), json);
cs.init();//呼叫方法
面向物件,一部分
document.getElementById("btn").onclick=function () {
document.getElementById("dv").style.backgroundColor="yellow";
};
原型複習
function Person(sex,age) {
this.sex=sex;
this.age=age;
}
//通過原型新增方法
Person.prototype.sayHi=function () {
console.log("打招呼,您好");
};
var per=new Person("男",20);
console.log(per.__proto__.constructor==Person.prototype.constructor);true
console.dir(Person);//建構函式的名字
var per2=new Person("女",30);
console.log(per.sayHi==per2.sayHi);true
建構函式、例項物件、原型物件
//原型的作用之一:共享資料,節省記憶體空間,需要共享的資料就可以寫原型中,不需要共享的資料可以寫在建構函式中
// //通過建構函式例項物件,並初始化 // var arr=new Array(10,20,30,40); // //join是方法,例項物件呼叫的方法 // arr.join("|"); // console.dir(arr); // //join方法在例項物件__proto__原型 // console.log(arr.__proto__==Array.prototype); true
* 建構函式可以例項化物件 * 建構函式中有一個屬性叫prototype,是建構函式的原型物件 * 建構函式的原型物件(prototype)中有一個constructor構造器,這個構造器指向的就是自己所在的原型物件所在的建構函式 * 例項物件的原型物件(__proto__)指向的是該建構函式的原型物件 * 建構函式的原型物件(prototype)中的方法是可以被例項物件直接訪問的
原型的用法-手動修改構造器
function Student(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
簡單的原型寫法
Student.prototype = {
//手動修改構造器的指向
constructor:Student,
height: "188",
weight: "55kg",
study: function () {
console.log("學習好開心啊");
},
eat: function () {
console.log("我要吃好吃的");
}
};
var stu=new Student("段飛",20,"男");
stu.eat();
console.log(stu.__proto__.height); 188
console.dir(Student);
console.dir(stu);
原型中新增的方法是可以相互呼叫的
function Animal(name,age) {
this.name=name;
this.age=age;
}
//原型中新增方法
Animal.prototype.eat=function () {
console.log("動物吃東西");
this.play();
};
var dog=new Animal("小蘇",20);
dog.eat();
物件使用屬性或方法,查詢策略(建構函式 原型)
* 例項物件使用的屬性或者方法,先在例項中查詢,找到了則直接使用,找不到則,去例項物件的__proto__指向的原型物件prototype中找,找到了則使用,找不到則報錯
function Person(age,sex) {
this.age=age;//年齡
this.sex=sex;
this.eat=function () {
console.log("建構函式中的吃");
};
}
Person.prototype.sex="女";
Person.prototype.eat=function () {
console.log("原型物件中的吃");
};
var per=new Person(20,"男");
console.log(per.sex);//男
per.eat();
console.dir(per);
為內建物件新增方法
*注意:這裡方法的呼叫不需要通過__proto__直接就可以實現呼叫
String.prototype.myReverse=function () {
for(var i=this.length-1;i>=0;i--){
console.log(this[i]);
}
};
var str="abcdefg";
str.myReverse();
//為Array內建物件的原型物件中新增方法
Array.prototype.mySort=function () {
for(var i=0;i<this.length-1;i++){
for(var j=0;j<this.length-1-i;j++){
if(this[j]<this[j+1]){
var temp=this[j];
this[j]=this[j+1];
this[j+1]=temp;
}//end if
}// end for
}//end for
};
var arr=[100,3,56,78,23,10];
arr.mySort();
console.log(arr);
String.prototype.sayHi=function () {
console.log(this+"哈哈,我又變帥了");
};
//字串就有了打招呼的方法
var str2="小楊";
str2.sayHi();
將區域性變數設定為全域性變數
//把區域性變數給window就可以了
函式的自呼叫---自呼叫函式
一次性的函式--宣告的同時,直接呼叫了
(function (win) {
var num=10;//區域性變數
//js是一門動態型別的語言,物件沒有屬性,點了就有了
win.num=num;
})(window);
console.log(num);
案例:把隨機數物件暴露給全域性物件window
*注意最後一行,原型方法的呼叫。
*設定為全域性的語法,易搞錯。這樣設定外部如果要使用必須new,如果通過new來設定外部,可以直接呼叫。下邊有案例
*自調函式一定要加上結尾的分號
通過自呼叫函式產生一個隨機數物件,在自呼叫函式外面,呼叫該隨機數物件方法產生隨機數
(function (window) {
產生隨機數的建構函式
function Random() {
}
在原型物件中新增方法
Random.prototype.getRandom = function (min,max) {
return Math.floor(Math.random()*(max-min)+min);
};
把Random物件暴露給頂級物件window--->外部可以直接使用這個物件
window.Random=Random;
})(window);
例項化隨機數物件
var rm=new Random();
呼叫方法產生隨機數
console.log(rm.getRandom(0,5));
console.log(Random.prototype.getRandom(0,5));
案例:隨機方塊
<style>
.map{
width: 800px;
height: 600px;
background-color: #CCC;
position: relative;
}
</style>
</head>
<body>
<div class="map"></div>
<script src="common.js"></script>
<script>
//產生隨機數物件的
(function (window) {
function Random() {
}
Random.prototype.getRandom=function (min,max) {
return Math.floor(Math.random()*(max-min)+min);
};
//把區域性物件暴露給window頂級物件,就成了全域性的物件
window.Random=new Random();
})(window);//自呼叫建構函式的方式,分號一定要加上
//產生小方塊物件
(function (window) {
//console.log(Random.getRandom(0,5));
//選擇器的方式來獲取元素物件
var map=document.querySelector(".map");
//食物的建構函式
function Food(width,height,color) {
this.width=width||20;//預設的小方塊的寬
this.height=height||20;//預設的小方塊的高
//橫座標,縱座標
this.x=0;//橫座標隨機產生的
this.y=0;//縱座標隨機產生的
this.color=color;//小方塊的背景顏色
this.element=document.createElement("div");//小方塊的元素
}
//初始化小方塊的顯示的效果及位置---顯示地圖上
Food.prototype.init=function (map) {
//設定小方塊的樣式
var div=this.element;
div.style.position="absolute";//脫離文件流
div.style.width=this.width+"px";
div.style.height=this.height+"px";
div.style.backgroundColor=this.color;
//把小方塊加到map地圖中
map.appendChild(div);
this.render(map);
};
//產生隨機位置
Food.prototype.render=function (map) {
//隨機產生橫縱座標
var x=Random.getRandom(0,map.offsetWidth/this.width)*this.width;
var y=Random.getRandom(0,map.offsetHeight/this.height)*this.height;
this.x=x;
this.y=y;
var div=this.element;
div.style.left=this.x+"px";
div.style.top=this.y+"px";
};
//例項化物件
var fd=new Food(20,20,"green");
fd.init(map);
console.log(fd.x+"===="+fd.y);
})(window);
</script>