js 对象原型链
<!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>