JavaScript高级程序设计第六章

ECMAScript有两种属性:数据属性和访问器属性

修改对象的属性的特性

var person = {};

Object.defineProperty(person,“name”,{
writeable:false,
value:“lala”
});

alert(person.name); //lala
person.name = “haha”;
alert(person.name); //lala
这个是无法修改name的值

var person = {};

Object.defineProperty(person,“name”,{
configurable:false,
value:“lala”
});

alert(person.name); //lala
delete person.name;
alert(person.name); //lala

访问器属性
例子:
var book = {
year :2018,
edition :1
};

Object.defineProperty(book,“year”,{
get:function(){
return this.year;
},
set:function(newValue){
this.year = newValue;
this.edition += newValue-2019;
}
});

book.year = 2020;
alert(book.edition); //2
只指定getter意味着属性不能写
只指定setter,意味着属性不能读

定义多个属性:
例子:
var book = {};

Object.defindProperty(book,{
year :{
value:2020
},

edition:{
	value:1
},

year:{set:funtion(newValue){
	this.year = newValue
},
	
          get:funtion(){
	return this.year;
}
}

});
把数据属性和访问器属性一起定义了

工厂模式,由于JavaScript没有类的定义,那么实现这个工厂模式是定义一个方法

function createPerson(name,age,job){

var obj = new Object();
obj.name = name;
obj.age = age;
obj.job = job;
obj.sayName = function(){
	alert(this.name);
	         };
return obj;

};

person1 = create(“lala”,18,“engineer”);

或者这样
function Person(name,age,job){

this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
	alert(this.name);
	         };

};//没有newObjct,没有return,使用this
var person2 = new Person(“haha”,20,“engineer”);

按照惯例,构造函数的名字开头是大写的

任何函数,用new来调用,那么它就是构造函数,只要不是用new来调用的,那么它就是普通函数

另一种方式来构造对象

fiction Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
};

var o = new Object();
Person.call(o,“lala”,20,“engineer”);

每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象

原型对象(共享属性和方法):

function Person(){}

Person.prototype.name = “lala”;
Person.prototype.age = 18;
Person.prototype.sayName = function(){
alert(this.name);
};

var person1 = new Person();
var person2 = new Person();

alert(person1.sayName == person2.sayName); //true

无论什么时候,只要创建一个新函数,就会为这个函数创建一个prototype属性,这个属性指向函数的原型对象

每当代码读取某个对象的属性,首先会查看对象实例本身有没有给定名字的属性,如果有就用了,没有就继续搜素指针指向的原型对象

var person = {};

function Person(){}

Person.prototype.name = “lala”;
Person.prototype.age = 18;
Person.prototype.sayName = function (){alert(this.name);};

var person1 = new Person();
person1.name = “haha”;
alert(person1.name); //haha

alert(person1.hasOwnProperty(“name”); //true,因为person1有自己的name属性,如果没有会返回false,通过这个 //方法可以很清楚知道,现在访问的这个属性是实例属性还是原型属性

in 的使用

var person = {};

function Person(){}

Person.prototype.name = “lala”;
Person.prototype.age = 18;
Person.prototype.sayName = function (){alert(this.name);};

var person1 = new Person();
alert(“name” in person1); //true

原型中的toString函数是不可枚举的

使用keys方法获取可枚举属性的字符串数组

var person = {};

function Person(){}

Person.prototype.name = “lala”;
Person.prototype.age = 18;
Person.prototype.sayName = function (){alert(this.name);};

var keys = Object.keys(Person.prototype); //注意这里如果写成Person是不行的

var person1 = new Person();
person1.name = “haha”;
person1.age = 20;
var key1 = Object.keys(person1); //注意这里如果写成person1.prototype是不行的

更常见的封装是
function Person() = {}

Person.prototype = {

name :"lala",
age :18,
sayName: function(){
alert(this.name);
}

};

var person = new Person();
alert(person.name); //lala

但是如果这样写
function Person(){}

var person = new Person();

Person.prototype = {

name :“lala”,
age :18
};

alert(person.name); //undefind

留给读者思考prototype指针,上面这种写法的prototype指针发生了变化

通过原生对象的原型,不仅可以用所有默认的方法,还有为它增加新的方法
例子:

String.prototype.startWith = function(text){
return String.indexOf(text) == 0;
};

var mas = “hello world”;
alert(mas.startWith(“h”); //true

我们一般都会使用混合模式来创建对象,既使用构造函数,也使用原型模式
例子:

function Person(name,age,job){

this.name = name;
this.age = age;
this.job = job;

}

Person.prototype.sayName = function(){

alert(this.name);

};

var person1 = new Person(“lala”,20,“engineer”);
var person2 = new Person(“haha”,20,“engineer”);

person1.sayName();
person2.sayName();

对13点的方法进行部分改造

function Person(name,age,job){

this.name = name;
this.age = age;
this.job = job;

if(typeof this.sayName != "function"){
Person.prototype.sayName = function(){
	alert(this.name);
}
}

}

var person1 = new Person(“lala”,20,“engineer”);
var person2 = new Person(“haha”,20,“engineer”);

person1.sayName();
person2.sayName();

重温一下call和apply方法
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.

Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args–>arguments)

call:和apply的意思一样,只不过是参数列表不一样.

Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表

分析: Person.apply(this,arguments);

this:在创建对象在这个时候代表的是student

arguments:是一个数组,也就是[“zhangsan”,”21”,”一年级”];

也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面

利用apply可以干很多事情:
例如:
求最大值的Math.max(里面只能传n个参数,不能传入数组)
但是这样写可以传入数组

var getMax = Math.max.apply(null,array);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值