ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JS知识点+试题(二)

2022-03-26 17:05:53  阅读:155  来源: 互联网

标签:function 知识点 console 试题 JS say log var name


作用域

 

 

 

循环陷阱

什么是循环陷阱?

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10
  • 由于匿名函数中使用的变量 i 在作用域外声明形成闭包
  • i 属于全局作用域
  • 所以循环中创建的匿名函数都指向同一个变量

循环陷阱就是看似每个新创建的函数都需要一个单独的变量,但没有实现

解决:

A.IIFE即时执行函数解决
var a = [];
for (var i = 0; i < 10; i++) {
  (function(n) {
    a[i] = function () {
    console.log(n);
  };
  })(i)
}
a[6](); // 6

B.ES6 使用let ——块级作用域

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

问:为什么块级作用域存在并使用?

答:在Javascript提出块级作用域,主要为了解决一个重要的设计缺陷 。
> 变量提升特性导致的大量与直觉不符的代码   SO,变量提升是什么?
(function() {
  console.log(v)
  var v = 123
})()//undefined

// 变量提升后
(function() {
  var v
  console.log(v)
  v = 123
})()
JS在变量声明提升的时候会将 var 声明的变量以及 用关键字函数声明的函数都会提升到当前作用域的顶端 。赋值语句在原地等待赋值。 优点是降低程序的编写难度,无明确顺序要求。
var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined

问:let是否会造成变量提升

var a = 8;
(function() {
  // let a 此时暂时性死区开始
  console.log(a); // Uncaught ReferenceError: x is not defined
  //暂时性死区结束
  let a = 1
}())
//报错

导致现象:

暂时性死区 (Temporal Dead Zone)
引用MDN上的定义
> let bindings are created at the top of the (block) scope containing the declaration, commonly referred to as “hoisting”. Unlike variables declared with var, which will start with the value undefined, let variables are not initialized until their definition is evaluated. Accessing the variable before the initialization results in a ReferenceError. The variable is in a “temporal dead zone” from the start of the block until the initialization is processed.
大概意思便是let同样存在变量提示(hoisting),只是形式与var不同,var定义的变量将会被赋予undefined的初始值,而let在被显式赋值之前不会被赋予初始值,并且在赋值之前读写变量都会导致 ReferenceError 的报错。从代码块(block)起始到变量求值(包括赋值)以前的这块区域,称为该变量的暂时性死区。 BUT,红宝书没有这样的叙述   答:不做判断型回答- 陈述客观事实    - 代码现象   - MDN与红宝书记述

 

this指向

function say() {
  console.log("我的家乡", this.name);
}
var bj = {
  name:'北京',
  say
}
window.name = "中国";
say(); // 我的家乡 中国
bj.say();// 我的家乡 北京

1.

普通函数

如果一个函数不属于任何一个对象,上下文就是全局对象。
在浏览器中就是window,如果是node运行时中就是global 2. 对象属性
接着说一下在对象中的this指向。this指向在对象中指向对象实例。其实归属某一个对象才是上下文环境使用最多的情况。同样一个方法可以根据对象实例中数据成员的不同产生不同的变化。 3. 构造函数与Class
类是对象实例,可以认为是实例的模板。
比如一个国家模板,实例一个国家比如中国。
当然国家模板中的say方法指向的创建的对象实例china    
function say() {
  console.log("我的家乡:", this.name);
}
function Country(name) {
  this.name = name
}
Country.prototype.say = say
const china = new Country('中国')
china.say() //我的家乡: 中国

ES6 

class关键字同理,构造函数constructor等同于上文中的Country构造函数
class Country {
  constructor(name) {
    this.name = name
  }
  say() {
    console.log("我的家乡:", this.name);
  }
}
const china = new Country('中国')
china.say()

 

4. call、apply、bind方法中
function say() {
  console.log('我的家乡:' + this.name)
}
window.name = '中国'
say()
say.apply({name : '北京'})
say.call({name : '朝阳'})
var mySay = say.bind({name: '曹县'}) mySay()

 

严格模式下this
//函数外指向window

"use strict"
console.log(this) // window
function foo() {
  console.log(this) // undefined
}
foo()

 


箭头函数
在箭头函数中,this总是指向词法作用域,也就是外层调用者。而不是方法所在对象。
function say() {
  console.log("我的家乡在"+this.name);
}
var bj = {
  name: "北京",
  say: () => say(),
  chaoyang: {
    name: "朝阳",
    say : () => say(), // 修改为箭头函数
  },
};
name = '中国'
bj.say(); // 我的家乡在中国
bj.chaoyang.say(); // 我的家乡在中国

 

标签:function,知识点,console,试题,JS,say,log,var,name
来源: https://www.cnblogs.com/clematis/p/16059662.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有