原型和闭包

原型和闭包

一切皆对象

一切皆对象(类型值除外)

undefined, number, string, boolean属于简单的值类型

函数、数组、对象、new Number(10)都是对象。他们都是引用类型

Null是基本数据类型,不是引用数据类型
基本数据类型的值就是它本身的值,引用数据类型是存放的对这个对象引用的指针,Null本身的值就是Null,所以不是引用类型

不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判
断为 object 类型, null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“ object ”。

http://www.cnblogs.com/xiaoheimiaoer/p/4572558.html

判断值类型的类型用typeof,引用类型的类型用instanceof

javascript为弱类型,里一切皆是对象,对象里面都是属性,而它的方法也是一种属性,用键值对的形式来表示,且javascript中的对象可以随意扩展属性,没有class的约束。

简单示例

var a1={b:10,c:function(n){alert(this.a+n);},d:{car:"000000",long:"五十"}
};

虽然函数是一种对象,但函数和对象那个之间更像是一种相互生成的关系

对象都由函数来创建,我们平时所写的var let等其实是一种“语法糖”其本质还是函数

prototype原型

每一个函数都有一个属性叫prototype

prototype的属性值是一个对象,只有一个默认的叫constructor属性,指向函数本身,而还我们可以自己采用自定义的形式在prototype中新增自己的属性

function F1(){}
F1.prototype.age="1982";
F1.prototype.sex=function(){return "man";
};

而这样做的作用就要联系到jQuery了

var $("div");
$div.attr('myAge','18');

上面代码中,$('div')返回的是一个对象,而对象被函数创建的而他的实现过程如下

myjQuery.prototype.attr=function(){};
$('div')=new myjQuery();

其本质就是

function F1(){}
F1.prototype.age="1982";
F1.prototype.sex=function(){return "man";
};
var f2=new F1();
console.log(f2.age);
console.log(f2.sex());

F1是一个函数,f2对象是从F1函数new出来的,这样f2对象就可以调用F1.prototype中的属性。

因为每个对象都有一个隐藏的属性——“proto”,这个属性引用了创建这个对象的函数的prototype。即:

f2.__proto__ === F1.prototype

这里的"______proto_______"成为“隐式原型”

__ proto__ 原型

每个函数function都有一个prototype,即原型。同时每个对象都有一个__ proto__

其指向创建该对象的函数的prototype

个__ proto __是一个隐藏的属性,javascript不希望开发者用到这个属性值,有的低版本浏览器甚至不支持这个属性值

自定义函数的prototype都是被Object创建,所以它的_ _proto__指向的就是Object.prototype

但是Object.prototype确实一个特例——它的__ proto__指向的是null,切记切记

函数也有原型

function fn(x,y){return x+y;
};
console.log(fn(10,20));var f1= new Function("x","y","return x+y;");
console.log(f1(8,7));

第二种为new Function仅作理解使用,Function作为函数,也是一种对象,所以也有 __ proto__ 属性,而函数本身是被Function创建,所以Function是被自身创建,他的 __ proto __指向了自身的Prototype。

同理Function.prototype指向的对象,它的__ proto __也指向Object.prototype

instanceof

instanceof 用于对引用类型的判断img

Instanceof的判断队则是:

function Foo(){}
var f1=new Foo();console.log(f1 instanceof Foo);//true
console.log(f1 instanceof Object);//true

设第一个变量为A,设第二个函数为B

沿着A的__ proto__这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,即同一个对象,那么就返回true。如果找到终点还未重合,则返回false

将前面的整合为整体如下图,通过此图,可以捋清为何返回值为true了

img

其实instanceof表示的就是一种继承关系,或者原型链的结构

继承

javascript中的继承是通过原型链来体现的

js是原型继承,C#是类型继承。
原型继承比类型继承更加灵活,但是又不如类型继承可控

function foo(){}
var f1=new foo();f1.a=10;Foo.prototype.a=100;
Fpp.prototype.b=200;console.log(f1.a);//10
console.log(f1.b);//200

f1是Foo函数new出来的对象f1.a是f1对象的基本属性而非。b从Foo.prototype得来

f1.__ proto __指向的是Foo.prototype

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

img

访问f1.b时,f1的基本属性中没有b,于是沿着__ proto__找到了Foo.prototype.b

可使用hasOwnProperty区分一个属性是基本属性还是原型

原型的灵活性

对象属性可以随时改动

在对象或函数new出来后可以随时加属性

继承方法不合适也可以随时修改

缺少你所要用的方法时,可以随时去创建

执行上下文

  • 变量、函数表达式——变量声明,默认赋值为undefined;
  • this——赋值;
  • 函数声明——赋值;

这三种数据的准备情况我们称之为“执行上下文”或者“执行上下文环境”。

函数每被调用一次,都会产生一个新的执行上下文环境。因为不同的调用可能就会有不同的参数

另外一点不同在于,函数在定义的时候(不是调用的时候),就已经确定了函数体内部自由变量的作用域

大白话理解:在执行代码之前,把将要用到的所有的变量都事先拿出来,有的直接赋值了,有的先用undefined占个空

了解了执行上下文环境中的数据信息,你就不用再去死记硬背那些可恶的面试题了

this

​ 在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了,因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。

  1. 构造函数

    所谓构造函数就是用来new对象的函数。其实严格来说,所有的函数都可以new一个对象,但是有些函数的定义是为了new一个对象,而有些函数则不是。另外注意,构造函数的函数名第一个字母大写(规则约定)

  2. 函数作为对象的一个属性

    如果函数作为对象的一个属性时,并且作为对象的一个属性被调用时,函数中的this指向该对象

  3. 函数用call或者apply调用

    当一个函数被call和apply调用时,this的值就取传入的对象的值。

  4. 全局 & 调用普通函数

    全局环境下,this永远是window

    普通函数在调用时,其中的this也都是window

其实,不仅仅是构造函数的prototype,即便是在整个原型链中,this代表的也都是当前对象的值。

执行上下文栈

​ 执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境。当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到全局上下文环境。处于活动状态的执行上下文环境只有一个。

其实这是一个压栈出栈的过程——执行上下文栈img

作用域

通常大家认为“javascript没有块级作用域”。所谓“块”,就是大括号“{}”中间的语句

javascript除了全局作用域之外,只有函数可以创建的作用域。

​ 所以,我们在声明变量时,全局代码要在代码前端声明,函数中要在函数体一开始就声明好。除了这两个地方,其他地方都不要出现变量声明。而且建议用“单var”形式

作用域有上下级的关系,上下级关系的确定就看函数是在哪个作用域下创建的

作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突

作用域在函数定义时就已经确定了。而不是在函数调用时确定

​ 作用域只是一个“地盘”,一个抽象的概念,其中没有变量。要通过作用域对应的执行上下文环境来获取变量的值。同一个作用域下,不同的调用会产生不同的执行上下文环境,继而产生不同的变量的值。所以,作用域中变量的值是在执行过程中产生的确定的,而作用域却是在函数创建时就确定了。

所以,如果要查找一个作用域下某个变量的值,就需要找到这个作用域对应的执行上下文环境,再在其中寻找变量的值

自由变量到作用域链

将变量在作用域外声明在作用域中调用的变量为自由变量

要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”,无论函数将在哪里调用

闭包

闭包,可理解为:函数作为返回值,函数作为参数传递

有些情况下函数在被调用完后其上下文环境不会被销毁,如返回值唯一个函数,函数的特别之处在于可以创建一个独立的作用域

使用闭包会增加内容开销,只有在所有闭包相关作用域执行完毕后才会销毁

图片来源于网络

转载于:https://www.cnblogs.com/baiyang2292/p/11175619.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文教会你何为重绘、回流?

文章目录css图层图层创建的条件重绘(Repaint)回流触发重绘的属性触发回流的属性常见的触发回流的操作优化方案requestAnimationFrame----请求动画帧写在最后学习目标: 了解前端Dom代码、css样式、js逻辑代码到浏览器展现过程了解什么是图层了解重绘与回流了解前端层…

js函数、js对象的这些点你真的懂吗?

本篇学习目标 ✨了解函数(高级)原型原型链概念\textcolor{green}{了解函数(高级)原型原型链概念}了解函数(高级)原型原型链概念 ✨掌握函数作用域\textcolor{green}{掌握函数作用域}掌握函数作用域 ✨掌握…

前端处理跨域的几种方式

什么是跨域&#xff1f; 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源&#xff0c;这里跨域是广义的。 广义的跨域&#xff1a; 1、资源跳转&#xff1a;A链接、重定向、表单提交 2、资源嵌入&#xff1a; <link>、<script>、<img>、<frame&g…

程序员必知的缓存套图

文章目录1. 线程与进程1.1 进程:1.2. 线程:1.3. 关系2. 浏览器内核模块组成4. 事件循环机制5. 缓存5.1. 缓存理解5.2. 缓存分类5.3. 缓存使用示意图5.4. 缓存中的header参数1. 线程与进程 1.1 进程: 进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进…

安装webpack及使用

前言 你是否也是只会运用框架中集成好的Webpack配置呢&#xff1f;你明白每一项的意义么&#xff1f;你懂多少Webpack的个性化配置项呢&#xff1f;本篇文章为你讲解Webpack中的各种配置项参数及作用&#xff01; 文章目录了解Webpack相关开启项目编译打包应用使用webpack配置…

php单例型(singleton pattern)

搞定&#xff0c;吃饭 <?php /* The purpose of singleton pattern is to restrict instantiation of class to a single object. It is implemented by creating a method within the class that creates a new instance of that class if one does not exist. If an obje…

助你提高效率的几个Vue指令

前言 很多使用Vue的同学往往最容易忽略的指令&#xff0c;由于在这里考虑到很多初学甚至还没有开始接触Vue的同学呢&#xff0c;在介绍v-clos之前呢就先以大家都熟知的v-model编写小demo v-model 相信大家对v-model并不陌生&#xff0c;简单来讲他就是用于在表单控件以及组建…

掌握Mock摆脱后端同学的束缚

文章目录前言Mock概述mock.js安装Mock规范Mock的使用总结前言 当下采用前后端分离模式开发Web应用已经成为气候&#xff0c;在开发阶段有一个不成文的规定则是 项目开发后端先行 但是作为前端开发工程师的我们&#xff0c;难道在搭建完页面后只能等待后端的接口么&#xff1f;…

Vue技能树上线啦

前言 前端现在越来越多样化&#xff0c;语言众多&#xff0c;大家使用的框架也比较杂&#xff0c;在广泛的前端技术栈面前我唯爱Vue&#xff08;仅代表个人观点勿喷小伙伴们&#xff09;可能很多人觉得我是因为简单&#xff0c;其实并不然&#xff0c;我尝试过很多框架&#x…

《SpringMVC从入门到放肆》一、概述

一、SpringMVC概述 ViewServiceDaoDBSpring MVCinterfaceinterfaceMysqlimplsimplsSpringMVC也叫Spring web mvc&#xff0c;属于表现层框架。SpringMVC是Spring框架的一部分&#xff0c;是在Spring3.0后发布的。 二、第一个SpringMVC程序功能描述&#xff1a;  用户提交一个…

手握流量密码,万粉不是梦

前言 可能大家来到CSDN的目的初衷都是不一样的&#xff0c;像我注册CSDN的时候完全是为了解决自己项目中的各种问题&#xff0c;能够有一个为我提供正确答案、正确解决方案的一个平台&#xff0c;简单的了解后我选择CSDN&#xff0c;直到成为现在的创作者也说明我的选择是对的…

秋季学期学习总结

转载于:https://www.cnblogs.com/zx666/p/10408950.html

一文带你了解React框架

前言 由于 React的设计思想极其独特&#xff0c;属于革命性创新&#xff0c;性能出众&#xff0c;代码逻辑却非常简单。所以&#xff0c;越来越多的人开始关注和使用&#xff0c;认为它可能是将来 Web 开发的主流工具。 这个项目本身也越滚越大&#xff0c;从最早的UI引擎变成…

Web前端JQuery面试题(一)

Web前端JQuery面试题&#xff08;一&#xff09; 一&#xff1a;选择器 基本选择器 什么是#id&#xff0c;element&#xff0c;.class&#xff0c;*&#xff0c;selector1, selector2, selectorN&#xff1f;答&#xff1a; 根据给定的id匹配一个元素&#xff0c;用于搜索&…

前端云原生——微信小程序云服务配置

前端同样涉及云原生前言创建使用云开发项目搭建云环境测试云服务1. 获取openid&#xff08;上传本地login云函数&#xff09;1.1 创建部署login文件时报错2. 自定义sum函数并创建部署3. 上传图片4. 前端操作数据库5. 即时通信demo面试法宝欢迎各位小伙伴们&#xff01; 为大家推…

45天带你玩转Node(第一天)初探Node.js

45天带你玩转Node 粉丝要求博主系统的写一篇关于Node.js的学习资料&#xff0c;但其实我们的Node.js知识点并不少&#xff0c;所以博主为大家搭建了一个专栏&#xff0c;为了方便大家系统的学习Node.js&#xff0c;大家记得订阅哦&#xff01;虽然我们的Node.js还很年轻&#…

【转载】 安卓版手机微信如何清理微信空间

在手机微信的使用过程中&#xff0c;随着手机微信使用的时间越长&#xff0c;手机微信占用的空间越大&#xff0c;其实手机微信存储了很多聊天记录包括图片、视频等大文件信息&#xff0c;此时如果手机存储空间比较紧张&#xff0c;可以使用微信自带的清理工具对手机微信空间进…

45天带你玩转Node(第二天)走进Node.js

45天带你玩转Node 粉丝要求博主系统的写一篇关于Node.js的学习资料&#xff0c;但其实我们的Node.js知识点并不少&#xff0c;所以博主为大家搭建了一个专栏&#xff0c;为了方便大家系统的学习Node.js&#xff0c;大家记得订阅哦&#xff01;虽然我们的Node.js还很年轻&#…

深入Vue原理_数据响应式

欢迎各位小伙伴们&#xff01; 为大家推荐一款刷题神奇哦 点击链接访问牛客网 各大互联网大厂面试真题。从基础到入阶乃至原理刨析类面试题 应有尽有&#xff0c;赶快来装备自己吧&#xff01;助你面试稳操胜券&#xff0c;solo全场面试官 数据响应式响应式是什么如何实现数据响…

python scipy样条插值函数大全(interpolate里interpld函数)

scipy样条插值 scipy样条插值1、样条插值法是一种以可变样条来作出一条经过一系列点的光滑曲线的数学方法。插值样条是由一些多项式组成的&#xff0c;每一个多项式都是由相邻的两个数据点决定的&#xff0c;这样&#xff0c;任意的两个相邻的多项式以及它们的导数(不包括仇阶导…