自调用函数
var name = 'world!';
// console.log(typeof name)
(function () {
console.log(this.name, name, typeof name, typeof name === undefined)
if(typeof name === undefined){
var name = 'a!'
console.log('hello ' + name)
} else{
var name = 'b!'
console.log('hello ' + name)
}
})();

运行结果是
"world!" undefined "undefined" false
hello b!

这里有两个陷阱
第一个是变量提升后 name 值为 undefined
第二个是 typeof name 为字符串 "undefined" 
 
闭包
闭包就是能读取其他函数内部变量的函数。
 
优点:
保护函数内的变量安全,加强了封装性
在内存中维持一个变量(用的太多就变成了缺点,占内存)
 
缺点:
闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生
var counter = 2
var add = (function () {
console.log(this.counter, counter, 'bbb') // 2, undefined, 'bbb'
var counter = 3;
return function () {
counter += 1;
console.log(counter)
}
})();
add(); // 4
add(); // 5
add(); // 6
console.log(counter, 'aaa') // 2, 'aaa'
 

原型链
所有对象的 __proto__ 都指向其构造器的 prototype
所有函数对象的 __proto__ 都指向 Function.prototype,它是一个空函数(Empty function)
Object.prototype.__proto__ === null

function fn() {
this.a = 10
this.b = function () {
console.log(this.a)
}
}
fn.prototype = {
b: function () {
this.a = 20
console.log(this.a)
},
c: function () {
this.a = 30
console.log(this.a)
}
}
var myfn = new fn();
console.log(myfn) //对象属性有a,b;原型链继承属性有b,c
console.log(myfn.__proto__ === fn.prototype) // true
console.log(myfn.__proto__ === myfn.constructor.prototype) // false
myfn.b() //10 
myfn.c() //30
myfn.b() //30
解析
myfn对象第一次调用b方法,由于原型链上的b方法被覆盖,所以始终调用自身的b方法,所以就输出初始值10
myfn调用c方法等于是调用继承的c方法,所以a属性被重新赋值,于是输出30
myfn第二次调用b方法,由于a属性已经被c方法重新赋值,所以继续输出30

myfn.__proto__始终指向构造器fn的prototype属性
但是myfn.__proto__不再指向myfn.constructor.prototype

myfn本身没有constructor属性,于是指向fn.prototype.constructor属性,
而fn.prototype.constructor本来应该指向其自身,但是因为重新赋值fn.prototype对象,所以fn.prototype的构造函数变成了Object

引用指针

var a = {n:1};
var b = a;
a.x = a = {n:2};
console.log(a.x); // undefined
console.log(b.x); // {n:2}

解释
这里的连续赋值运算顺序是先进行'.'运算符赋值,这时将a.x还是指向对象A的,
接下来开始从右向左赋值,改变a的指向为对象B
接下来开始a.x的赋值为对象B,这时候'.'运算符已经最先赋值了,所以还是给对象A的x属性赋值

js学习笔记之自调用函数、闭包、原型链的更多相关文章

  1. JS学习笔记(三)函数

    js中的方法名一般都是首字母小写,其余单词首字母大写的规范. 声明 function 函数名(参数列表) { // 函数体 return 返回值; } 调用 函数名(); (js中花括号喜欢用这种方式 ...

  2. 【JS学习笔记】关于function函数

    函数的基本格式 function 函数名() { 代码: } 函数的定义和调用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...

  3. js学习笔记20----addClass,removeClass函数封装

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. JS学习笔记 - fgm练习 2-5 - 函数传参 设置div样式

    练习地址:http://www.fgm.cc/learn/lesson2/05.html <script> window.onload = function(){ var oDiv = d ...

  5. JS 学习笔记--9---变量-作用域-内存相关

    JS 中变量和其它语言中变量最大的区别就是,JS 是松散型语言,决定了它只是在某一个特定时间保存某一特定的值的一个名字而已.由于在定义变量的时候不需要显示规定必须保存某种类型的值,故变量的值以及保存的 ...

  6. WebGL three.js学习笔记 使用粒子系统模拟时空隧道(虫洞)

    WebGL three.js学习笔记 使用粒子系统模拟时空隧道 本例的运行结果如图: 时空隧道demo演示 Demo地址:https://nsytsqdtn.github.io/demo/sprite ...

  7. WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法

    WebGL学习----Three.js学习笔记(5) 点击查看demo演示 Demo地址:https://nsytsqdtn.github.io/demo/360/360 简单网格材质 MeshNor ...

  8. WebGL three.js学习笔记 创建three.js代码的基本框架

    WebGL学习----Three.js学习笔记(1) webgl介绍 WebGL是一种3D绘图协议,它把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的 ...

  9. vue.js 学习笔记3——TypeScript

    目录 vue.js 学习笔记3--TypeScript 工具 基础类型 数组 元组 枚举 字面量 接口 类类型 类类型要素 函数 函数参数 this对象和类型 重载 迭代器 Symbol.iterat ...

随机推荐

  1. NOIP模拟测试24「star way to hevaen·lost my music」

    star way to heaven 题解 大致尝试了一下并查集,记忆化搜索,最小生成树 最小生成树是正解,跑最小生成树然后找到最大的值 欧几里德距离最小生成树学习 prim楞跑 至于为什么跑最小生成 ...

  2. 基于ILI9341的TFT液晶显示模组LCM240320详解(1)

    Hello,大家好,今天我们来讨论当下非常流行的TFT液晶显示模组,它最大的特点是可以显示出效果非常好的彩色信息,绝大多数手机.液晶显示器,液晶电视.MID.MP4等产品都在使用它,你想抗拒它的魅力还 ...

  3. 什么是TCP和UDP?

    1.什么是IP和TCP? Internet协议(IP)是Internet的地址系统,具有将数据包从源设备传递到目标设备的核心功能.IP是建立网络连接的主要方式,奠定了Internet的基础.IP不负责 ...

  4. Spring学习日记02_IOC_属性注入_其他类型属性

    ICO操作Bean管理(xml注入其它类型属性) 字面量 null值 <property name="address"> <null></null&g ...

  5. 关于Word转Markdown的工具Writage安装及使用

    简介 Writage是为希望开始编写结构良好的文档,没有时间或不想深入了解 Markdown 语法的详细信息,或者更愿意使用 Word 作为文本编辑器的每个人设计的 下载并安装 安装包地址:https ...

  6. 46、django工程(view)

    46.1.django view 视图函数说明: 1.http请求中产生两个核心对象: (1)http请求:HttpRequest对象. (2)http响应:HttpResponse对象. 2.vie ...

  7. hbuilder 开发app 自动升级

    使用huilder 开发app  ,实现app升级功能 1. var wgtVer = null; //用于获取系统当前版本 var currentversion = null; //用于获取系统最新 ...

  8. Redis 过期时间解析

    文章参考:<Redis 设计与实现>黄建宏 设置过期时间 通过 EXPIRE 或者 PEXPIRE 命令,客户端可以以秒或毫秒精度为数据库中的某个键设置生存时间 TTL (Time To ...

  9. 适合企业的CRM系统选型法则?

    在市场竞争激烈的今天,企业需要找到一款好用的企业CRM系统来帮助维护客户关系,同时也能够帮助企业进行销售管理.营销管理,CRM可以说是当代企业管理的最强工具之一.那么适合企业的CRM客户管理系统要如何 ...

  10. Linux基础 -03

    2.2.3 head-tail 命令 #------head #head pass #查看头部内容,默认前10行 #head -n5 pass #查看头部前5行,使用-n指定 #-------tail ...