【Javascript】面向对象编程,this,原型与原型链,类与实例
❤️ Author: 老九
☕️ 个人博客:老九的CSDN博客
🙏 个人名言:不可控之事 乐观面对
😍 系列专栏:
文章目录
- 对象中的方法/this
- this使用
- bind函数
- 原型
- 原型链
- 类与实例
- class
对象中的方法/this
- 面向对象:核心思想就是可以为每种事务(东西),在编程语言中建立一个对应的类型,对应到语言里就是一个class
- 反引号:中间可以插入${}作为动态字符串
- 其实对象中函数的调用就是方法,foo和bar就当作obj对象的方法调用
- 其中foo的this就是指代的obj对象,bar的this指代的也是obj这个对象
<script>
obj = {
foo: function () { },
bar: function () { },
}
let rabbit = {}
rabbit.speak = function (line) {
console.log(`the rabbit says ${line}`)
}
</script>
this使用
- this是函数的一个隐含参数,其值不是传入的,而是取决于该函数的调用方式,不取决于函数在哪定义和在哪调用
- f() = obj.foo
f() // 当函数调用,里面的this指向window
obj.foo() //当obj的方法调用,里面的this指向obj
他们两个的this是不同的 - 这个this指代的是添加的属性对应的对象
<script>
a = [1, 2, 3]
a.push2 = function (val) {
this[this.length] = val
return this.length
}
a.forEach2 = function (action) {
for (var i = 0; i < this.length; i++) {
action(this[i])
}
</script>
-
这个speak是对象属性的简写,speak属性来源于能够读到的一个speak函数的变量名
-
js语言中,函数从来不属于一个对象,this也不会因为这种属于而一成不变
-
在js中,如果两个对象分别有一个属性指向同一个函数,则该函数和这两个对象之间的关系是对等的
<script>
function speak(line) {
console.log(`the ${this.type} rabbit says ${line}`)
}
let whiteRabbit = {
type: "white",
speak
}
let hungryRabbit = {
type : "hungry",
speak
}
speak.call(hungryRabbit,"woshizhu")
</script>
- 在call方法和apply方法中,第一个参数传的就是this,call和apply唯一的区别就是第二个参数apply传的是数组,而call后面传的是一个一个的参数,由此来看apply更好用一些,因为如果数组可以是一个变化的值,而call的话只能是传固定的参数
- 所以,如果一个函数中创建了另一个函数,那么内层函数是拿不到外层函数的this的,除非是外层函数通过call方法,把外层函数的this和内层函数指向同一个函数
- this不能出现在等号的左边,即this本身不能被赋值,this的绑定关系不能被改变。
- 箭头函数是没有this的,在箭头函数里读this,就跟在读一个箭头函数内部没有声明的变量一样。读箭头函数的this,就是读箭头函数外面函数的this
- 由于call/apply并不能改变箭头函数里的this,所以一般都不会使用call和apply来调用箭头函数。apply传不定数量参数的功能由展开运算符。。。来提供。
bind函数
- bind函数的第一个参数是绑定this,如果bind的this已经被绑定了,那么就不能再次更改绑定了
原型
- 从这里我们可以看到,js从一个空对象里取出了一个属性;如果你在一个对象上找不到对应的属性,就会在这个原型对象上找,原型就相当于是一个后备源;所以任何一个对象都有toString的方法,这个方法就是在原型上的
- Object.getPrototypeOf({})这个可以获得对象的原型,object.prototype这个是获取object上的一个属性,这个属性指向原型对象,所以他俩是相等的;数组的原型的原型是对象的原型;最终Object.getPrototypeOf(Object.getPrototypeOf({}))的原型是null
- Object.getPrototypeOf([]) === Array.prototype
- Object.getPrototypeOf(function(){}) === Function.prototype
- Array.prototype和Function.prototype都以Object.prototype为原型
- 这个双中括号phototype就是原型,双中括号代表对象的内部的状态
- 如果想要看到函数的内部状态,用console.dir()
- 还有一点就是不会因为给一个对象的属性赋值而赋值到其原型对象上
原型链
- js就是通过原型链的方式实现了面向对象的
- 原型链在js中其实也只是指针(对象的指向关系 )
- 原型链存在的作用一方面是为了继承,另一方面是为了节省空间;如果一组对象都想有某些方法/属性,则把这些共用的方法/属性放到它们的原型上,可以节省存储空间
类与实例
- 补充一个语法:当在对象的属性中,一个属性指向一个函数(必须是function函数),可以直接将冒号和function删除
- 怎样自己创建原型对象呢?通过Object.create(xxx)
class
- class就是定义了一个类型,构造函数就是一个所有的基础
<script>
var protoRabbit = {
speak(line) {
console.log(`the ${this.type} rabbit says ${line}`)
}
}
function makeRabbit(type) {
let rabbit = Object.create(protoRabbit)
rabbit.type = type
return rabbit
}
var killRabbit = makeRabbit('killer')
var yellowRabbit = makeRabbit('yellowRabbit')
</script>
- 这样写等价于上面那么写,更加方便
- 原型里面就写一些基础的公共方法,然后构造函数就传值,然后用new创建对象
<script>
function Rabbit(type) {
this.type = type
}
Rabbit.prototype = {
speak(line) {
console.log(`the ${this.type} rabbit says ${line}`)
}
}
new Rabbit(yellow);
</script>
- 构造函数的prototype属性 仅仅是作为其构造出来的实例的原型;其实所有的普通函数(非箭头函数)都有prototype属性,但我们一般只关心构造函数的prototype属性
- 除了undifined和null,任何值都有原型,即_ proto 属性, proto _属性就是原型,要区别于原型和构造函数的原型属性
也就是说Object.getPrototypeOf(Rabbit) == Function.prototype
- 上面的那个叫原型属性,下面的那个叫原型,一般如果是构造方法的话,我们就设置上面的那个,也就是设置所谓的原型属性
————————————————————————
♥♥♥码字不易,大家的支持就是我坚持下去的动力♥♥♥
版权声明:本文为CSDN博主「亚太地区百大最帅面孔第101名」的原创文章