<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
//對象建立
//1、單例模式: /*對象資料類型的作用:把描述同一個事物(同一個對象)的屬性和方法放在一個記憶體空間下,起到了分組的作用,這樣不同僚物之間的屬性即使用屬性名相同,互相也不會發生沖突 我們把這種分組編寫代碼的模式叫做單例模式,在單例模式中我們把p1 p2也叫做命名空間 */
var p1 = {
name: "aa",
age: 12
};
var p2 = {
name: "bb",
age: 22
};
//2、工廠模式:函數封裝
function createJsPerson(name, age) {
var obj = {};
obj.name = name;
obj.age = age;
obj.writeJs = function() {
console.log("my name is " + this.name + ",start study js");
};
return obj;
};
var zs = createJsPerson("zhangsan", 12);
zs.writeJs();
var ls = createJsPerson("lisi", 16);
ls.writeJs();
//3、js是一種輕量級程式設計語言 封裝 繼承 多态 html css是标記語言 js沒有方法重載 (但通過方法getNum可以類似實作重載)
function getNum(num) {
if (typeof num == "undefined") {
return 0;
}
return num;
};
getNum(); //類似實作重載了
getNum(100);
//4、構造函數模式:建立一個自定義類,并且建立這個類的執行個體
//與工廠模式差別:1、工廠模式建立對象 createJsPerson("zhangsan", 12) 構造函數模式 new Person("zhangsan", 12) 2、構造函數模式不需要手動建立對象,浏覽器預設會建立目前類的執行個體this并傳回 3、若構造函數模式有手動傳回基本資料類型(return 100)的則目前執行個體沒影響 若手動傳回了一個對象{name:"ccc"}則目前執行個體為手動傳回的對象
//js中所有的類都是函數資料類型的,所有的類的執行個體都是對象類型
function Person(name, age) {
this.namex = name;
this.age = age;
this.writeJs = function() {
console.log("my name is " + this.namex + ",start study js");
}
};
var p1 = new Person("zhanghai", 33); //var pp1=Person("lisi",22) 此處pp1 undefined
p1.writeJs();
function Fn() {
var num = 10; //是方法私有變量與Fn執行個體fn1沒有任何關系
this.namexx = "dddd"; //this->fn1
this.getName = function() {
console.log(this.namexx); //this需看getName執行進修才知道
};
this.fun1 = function() {
console.log(this.namexx);
}
};
var fn1 = new Fn; //預設類沒有參數new時小括号可以省略
fn1.getName(); //輸出"dddd"
var ss1 = fn1.fun1;
ss1(); //輸出 undefined this-》window
console.log(fn1.getName === fn1.getName); //false name getName都是執行個體的私有屬性,若要有公共屬性需要用原型鍊
console.log(fn1.num); //輸出 undefined
console.log("name" in fn1); //in 檢測某一屬性是否屬于這個對象,不管是私有的屬性還是公有的屬性
console.log(fn1.hasOwnProperty("name")); //hasOwnProperty:用來檢測某一屬性是否為這個對象的私有屬性,隻檢測私有屬性
//5、基于構造函數模式的原型鍊:1、每一個函數資料類型(普通函數、類)都有一個天生自帶的屬性prototype,并且這個屬性是一個對象類型的,2、并且浏覽器在prototype增加了一個constructor(構造函數),屬性值是目前函數本身。3、每一個對象類型(普通對象,prototype,執行個體)也天生自帶一個屬性__proto__,其屬性值是目前執行個體類的原型prototype
function Animal() {
this.age = 4;
this.show = function() {
console.log(this.age);
};
};
Animal.prototype.pp = function() {
console.log("ddddd", this.age)
};
var animal1 = new Animal();
console.log(Animal.prototype)
console.log(animal1.__proto__.constructor)
Animal.prototype.pp==animal1.__proto__.pp //true
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
function Fn() {
this.num = 10;
};
Fn.prototype = { //自定義Fn原型會,若内置的類原型不允許自定義,但也可改部分Array.prototype.sort=function(){}
constructor: Fn,
a: function() {
},
b: function() {
}
};
var fn = new Fn;
console.log(fn);
var obj = {
name: "howhy",
age: 22
};
obj.__proto__.aaa = function() {
console.log(4444);
};
for (var key in obj) { //預設會把自己私有的和自己所屬類原型上擴充的屬性和方法周遊
if (obj.propertyIsEnumerable(key)) { //propertyIsEnumerable 私有屬性 hasOwnProperty
console.log(obj[key]); // "howhy" 22
}
};
var obj2 = Object.create(obj); //将對象obj作為obj2對象的原型
//原型繼承 子類若将繼承父類所有屬性和方法 則需将子類的prototype=父類的執行個體 這樣的父類公有+私有都成了子類公有的
function A() {
this.x = 10;
}
A.prototype.getX = function() {
console.log(this.x);
}
function B() {
this.getY = function() {
console.log(2222)
}
}
B.prototype = new A;
var b = new B();
b.getX();
//call apply bind
function fun() {
console.log(this)
}
Function.prototype.mycall = function(context) {
this();
// this.name = this;
// this.name();
context[this.name] = this();
console.log(context)
}
fun();
fun.call({})
fun.mycall({})
</script>
</body>
</html>