javascript函数和面向对象的学习笔记

方法和属性索引

函数中的方法和属性

arguments和this属性

arguments是类数组对象,包含着传入函数中的所有参数
this引用的是函数执行的环境对象

callee属性

该属性是一个指针,指向拥有这个arguments对象的函数

function factorial(num) {
   if(num <= 1){
       return 1;
   }else{
       return num * factorial(num - 1);
   }
}

function factorial(num) {
   if(num <= 1){
       return 1;
   }else{
       return num * arguments.callee(num - 1);
   }
}

let trueFactorial = factorial;
factorial = ()=>{
   return 0;
};
alert(trueFactorial(5))//120
alert(factorial(5))//0

caller属性

这个属性保存着调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值为null

function outer() {
    inner();
}
function inner() {
    alert(inner.caller)
};
outer()

以上代码会导致警告窗中显示outer()函数的源代码。因为outer()调用了inner(),所以inner.caller()就指向了outer()。为了实现更松散的耦合,也可以通过arguments.callee.caller来访问相同的信息

apply()方法

在特定的作用域中调用函数值。实际相当于设置函数体内的this对象的值,接受两个参数,一个是在其中运行函数的作用域,另一个是参数数组

function sun(num1, num2) {
    return num1 + num2;
}

function callSum1(num1, num2) {
    return sun.apply(this, arguments);
}

function callSum2(n1, n2) {
    return sun.apply(this, [n1, n2]);
}

alert(callSum1(10, 10));//20
alert(callSum2(10, 10));//20

call()方法

类似于apply()方法,不同在于第二个参数,call方法需要将传递给函数的方法逐个列举出来

function sun(num1, num2) {
    return num1 + num2;
}

function callSum1(num1, num2) {
    return sun.call(this, num1, num2);
}


console.log(callSum1(10, 10));//20

call和apply真正的强大之处在于能够扩充函数赖以生存的作用域

window.color = "red";
let o = {color:'blue'};
function sayColor() {
    console.log(this.color)
}
sayColor();//red
sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue

面向对象中的方法和属性

Object.defineProperty()

主要用于设置对象的数据属性

//设置person的name数据属性不能被更改
let person = {}
Object.defineProperty(person, "name", {
	writable:false,
	value:"Nicholas"
});
alert(person.name);//"Nicholas"
person.name = "Greh";
alert(person.name)//"Nicholas"
//设置book的访问器属性
let book = {
	_year:2004,
	edition:1
};
Object.defineProperty(book, "year", {
	get:()=>{
	return this._year;
	},
	set:newValue=>{
	if(newValue > 2004){
	this._year = newValue;
	this.edition += newValue -2004;
	})

Object.getOwnPropertyDescriptor()

可以取得给定属性的描述符

let descriptor = Object.getOwnPropertyDescriptor(person, "name");
console.log(descriptor.writable) //false

constructor

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayname = ()=>{
        console.log(this.name);
    }
}

let person1 = new Person("nicholas", 29, "software Engineer");
let person2 = new Person("Greg", 27, "Doctor")

person1,person2分别保存着Person的一个不同的实例。两个对象都有constructor属性,该属性指向Person,如下所示

console.log(person1.constructor == Person);//true
console.log(person2.constructor == Person);//true

prototype

这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。prototype就是通过调用构造函数而创建的那个对象实例共享它所包含的属性和方法

function Person() {
}

Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "software Engineer";
Person.prototype.sayname = ()=>{
    alert(this.name)
};
let person1 = new Person();
person1.sayname();//"Nicholas"
let person2 = new Person();
person2.sayname();//"Nicholas"
alert(person1.sayname == person2.sayname)//true

isPrototypeof()

通过该方法来确定对象之间是否存在引用[[Prototype]]的关系

alert(Person.prototype.isPrototypeOf(person1))//true

hasOwnProperty()

该方法用于检测给定属性是存在于实例中还是存在于原型中,如果存在于原型中,返回false;若存在于实例中则返回true。

alert(person1.hasOwnProperty("name"))//false
person1.name = 'Greg';
alert(person1.name);//Greg
alert(person1.hasOwnProperty('name'))//true

in操作符

in操作符会在对象能够访问给定属性时返回true,无论该属性存在于原型还是实例中

//下面的函数用于检测属性是否存在于原型中,如果存在于原型中返回true
function hasPrototypeProperty(object, name) {
    return !object.isPrototypeOf(name) && (name in object)
}

Object.keys()

要取得对象上所有可枚举的实例属性,这个方法接受一个对象作为参数,返回一个包含所有可枚举属性的字符串数组

let keys = Object.keys(Person.prototype);
alert(keys)//"name, age, job, sayName"
let p1 = new Person();
p1.name = "Rob";
p1.age = 31;
let p1keys = Object.keys(p1);
alert(p1keys)//"name, age"

猜你喜欢

转载自blog.csdn.net/qq_37717458/article/details/88659675