<!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>