js闭包、原型、继承、做用域

做用域:javascript

做用域是针对变量而言的,好比定义了一个函数啊a1,a1里面又定义一个子函数a2,此时就会有三个做用域  全局做用域--a1做用域--a2做用域java

当a2查找变量时会先从自身的做用域开始查找,找不到就向上一级做用域a1查找,直到全局做用域,这就造成了一个做用域链react

原型:设计模式

javascript中,一切皆对象,每一个对象都会会有一个_propo_属性(浏览器自动建立),该属性指向它的原型,当一个对象查询一个属性的时候,自身没有就会根据_propo_向原型查找,直到object.prototype._propo_为null,这样就造成了一个原型链浏览器

prototype是什么呢?闭包

咱们直到咱们能够经过一个构造函数建立一个类,prototype的做用就是让类的属性能够被继承,因此只有构造函数才有prototype这个属性app

继承:函数

javascript中的继承是经过原型链来体现的。先看几句代码学习

以上代码中,f1是Foo函数new出来的对象,f1.a是f1对象的基本属性,f1.b是怎么来的呢?——从Foo.prototype得来,由于f1.__proto__指向的是Foo.prototypethis

访问一个对象的属性时,先在基本属性中查找,若是没有,再沿着__proto__这条链向上找,这就是原型链

那么咱们在实际应用中如何区分一个属性究竟是基本的仍是从原型中找到的呢?你们可能都知道答案了——hasOwnProperty,特别是在for…in…循环中,必定要注意。

 

等等,不对! f1的这个hasOwnProperty方法是从哪里来的? f1自己没有,Foo.prototype中也没有,哪儿来的?

好问题。

它是从Object.prototype中来的,请看图:

对象的原型链是沿着__proto__这条线走的,所以在查找f1.hasOwnProperty属性时,就会顺着原型链一直查找到Object.prototype。

 

因为全部的对象的原型链都会找到Object.prototype,所以全部的对象都会有Object.prototype的方法。这就是所谓的“继承”。

固然这只是一个例子,你能够自定义函数和对象来实现本身的继承。

 

说一个函数的例子吧。

咱们都知道每一个函数都有call,apply方法,都有length,arguments,caller等属性。为何每一个函数都有?这确定是“继承”的。函数由Function函数建立,所以继承的Function.prototype中的方法。不信能够请微软的Visual Studio老师给咱们验证一下:

看到了吧,有call、length等这些属性。

那怎么还有hasOwnProperty呢?——那是Function.prototype继承自Object.prototype的方法。有疑问能够看看上一节将instanceof时候那个大图,看看Function.prototype.__proto__是否指向Object.prototype。

 

原型、原型链,你们都明白了吗?

 

 

JavaScript 闭包与类(原型链)之间的开发方式?

最近遇到一个问题.关于如何利用闭包开发与如何利用原型链开发.
本身看了一本书《JavaScript设计模式与开发实践》 里面有一章提到了高阶函数.并且在这本书不少设计模式都能利用闭包来实现.等等之类的.
本身在学习的过程当中也一直不明白类(原型链)的开发与闭包的开发
好比用构造函数写个类
function Girl(name){
this.name=name
}
Girl.prototype.sayname=function(){console.log(this.name)}
这也能够用闭包来实现
var Girl=function(name){
var girlname=name;
var sayname=function(){
console.log(name)
}
return {
sayname:sayname
}
}
那么问题来了。

如何利用闭包来编写程序和如何利用原型链来编写程序,这两种编写模式有什么差异。如何写才是最佳的方式。在什么状况下使用原型链模式来编写?什么状况下使用闭包来编写?

这是个很宽泛的问题,利用闭包和原型能干什么事情。我从你题中的应用场景,分析下用原型和用闭包实现的不一样点。
案例1:
function Girl(name){
this.name=name
}
Girl.prototype.sayname=function(){console.log(this.name)}
var a = new Girl('Lucy');
var b = new Girl('Lily');
案例2:
var Girl=function(name){
var sayname=function(){
console.log(name)
}
return {
sayname:sayname
}
}
var a = Girl('Lucy');
var b = Girl('Lily');
案例1中,a,b的结构以下图所示(一些无关的属性没有彻底画出):


案例2中,a,b的结构以下图所示(一些无关的属性没有彻底画出):

咱们来对比下二者的区别以及缘由:
1. 方案1中:构造出来的对象a、b,经过原型共享sayname方法;方案2中生成的对象a、b各有本身的属性方法sayname(空间上浪费)。这就是原型设计的初衷。咱们经过这里也看到了自身属性和原型属性的区别(顺便说下能够经过hasOwnProperty属性来区分)。
2. 方案1中:构造出来的对象a、b各有本身的属性name,咱们能够经过a.name,b.name来访问这个属性;方案2中,生成的对象a、b并无属性name,而他们的方法属性sayname的做用域链上有name变量,在sayname方法里面能够访问name变量。咱们看到方案1中的name属性具备面向对象中的公有属性的特性,而方案二中name具备面向对象中的私有属性的特性。

 

关于闭包,我在内网论坛写过一篇文章,有童鞋转载到csdn JS闭包 - JokerWILL ,有兴趣能够看下。

因此咱们要了解原型和闭包的特性,了解使用原型和闭包会产生怎样不一样的结果,根据咱们的需求来灵活的使用。

题主这问题问得....
原型链是干什么用的,是共享属性和方法,是能够实现继承的
闭包是对变量和方法的封装,能够延迟使用外部变量和方法

构造函数上的方法是每一个实例对象都有这个方法,彼此不一样

原型链的方法是各个实例对象共享这个方法

首先明白概念是什么,可以干什么用,再说什么模式一类的东西,模式是大量实践总结出来的通用作法,js高级程序设计,必定多看几遍
相关文章
相关标签/搜索