javascript知识点

目录

词法作用域

1.js字符串和数组

1.js中slice和concat,indexOf也可以用于字符串

2.for in 和for of的遍历异同

2.页面内有一个 input 输入框,实现在数组 arr 查询命中词并和 autocomplete 效果。

3.函数的长度length


1.词法作用域和this

例1:自由变量作用域

var name = '张三';

function showName() {
    console.log(name);
}

function changeName() {
    var name = '李四';
    showName();
}

changeName();

张三
 在函数作用域中showName中没有找到name字段,

那么会往更外层作用域去寻找该变量的定义

外边一层就是全局作用域neme='张三‘’

 例2:结合结合变量提升

var a = 1;
function test(){
    a = 2;
    return function(){
        console.log(a);
    }
    var a = 3;
}
test()();
2

var声明变量会进行提升,所以函数test中的var a会被提升到a=2前面

上边等价于:

var a = 1;
function test(){
var a;
    a = 2;
    return function(){
        console.log(a);
    }
    a = 3;
}
test()();

4.this指向

// 声明位置
var me = {
  name: '张三',
  hello: function() {
    console.log(`你好,我是${this.name}`)
  }
}

var you = {
  name: '李四',
  hello: me.hello
}

// 调用位置
me.hello() 
you.hello() 
VM102:5 你好,我是张三
VM102:5 你好,我是李四
undefined
各位看到 hello 在代码中分别被 me 和 you 调用了,因此两次调用的 this 也就分别指向了 me 和 you

5.直接调用函数本身,this指向window

// 声明位置
var me = {
  name: '张三',
  hello: function() {
    console.log(`你好,我是${this.name}`)
  }
}

var name = '李四'
var hello = me.hello 

// 调用位置
me.hello() 
hello() 
VM479:5 你好,我是张三
VM479:5 你好,我是李四
undefined
// 声明位置
var me = {
  name: '张三',
  hello: function() {
    console.log(`你好,我是${this.name}`)
  }
}

var you = {
  name: '李四',
  hello: function() {
    var targetFunc = me.hello
    targetFunc()
  }
}

var name = '王五'

// 调用位置
you.hello()

VM482:5 你好,我是王五
undefined

在三种特殊情境下,this 会 100% 指向 window:

立即执行函数(IIFE)
setTimeout 中传入的函数
setInterval 中传入的函数

6.箭头函数中this

var a = 1

var obj = {
  a: 2,
  // 声明位置
  showA: () => {
      console.log(this.a)
  }
}

// 调用位置
obj.showA() // 1

当我们将普通函数改写为箭头函数时,箭头函数的 this 会在书写阶段(即声明位置)就绑定到它父作用域(函数作用域和全局作用域)的 this 上。无论后续我们如何调用它,都无法再为它指定目标对象 —— 因为箭头函数的 this 指向是静态的,“一次便是一生”。

 

 

 

2js字符串和数组

1.js中slice和concat,indexOf也可以用于字符串

2.for in 和for of的遍历异同

  在讲解完javaScript中其他几种遍历数组的方法后,我们来看一下for in 和for of的遍历异同

  for in 循环阔以用来遍历对象的可枚举属性列表(包括[[Prototype]]链)。使用for in遍历对象无法直接获取到值,但是for of能取到值(前提对象本身定义了迭代器)

1

2

3

4

5

6

7

8

9

10

11

console.log('for...in');

let arr = ['d''s''r''c'];

for (const key in arr) {

    if (arr.hasOwnProperty(key)) {

        console.log(key);

    }

}

console.log('for...of');

for (const iterator of arr) {

    console.log(iterator);

}

  结果:

 

   

  简单总结就是,for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。

  for-in总是得到对象的key或数组、字符串的下标。

  for-of总是得到对象的value或数组、字符串的值,另外还可以用于遍历Map和Set


3.页面内有一个 input 输入框,实现在数组 arr 查询命中词并和 autocomplete 效果。

效果
忽略圆圈,这是quickTime录屏的side effect。。。


代码
html

 <div id="div1">
    <input type="text" id="input" placeholder="有autocomplete的输入框"/>
    <ul id="ul">
    </ul>
  </div>



css

*{
    margin: 0;
    padding: 0;
    box-sizing:border-box;

}
#div1{
    margin:200px auto;
    position: relative;
}

ul{
    list-style: none;
    margin: 0 auto;
    background-color: #ededed;
    color: #3b200c;
    width: 400px;
    border: none;
}

li{
    cursor: pointer;
}

input{
    display: block;
    margin: 0 auto;
    line-height: 40px;
    height: 40px;
    width: 400px;
    font-size: 20px;
    background-color: #ede387;
    border: none;
}


js

var arr = ['a','apple','abandon','bilibili','beep','before','become','being','highmaintains','by','bye','banana']

input.addEventListener('input', function(event){

    var _value = event.target.value.trim()

    if(_value){

        autoComplete(_value, arr)
    }

    else{

        ul.innerHTML = ''
    }

})


function autoComplete(str, arr){

    var lis = []

    arr.forEach( (word)=>{

        if(word.startsWith(str)){

            lis.push('<li>' + word + '</li>')
        }
    })

    ul.innerHTML = lis.join('')
}

function addToInput(li){

    var _txt = li.innerText

    input.value = _txt
}

ul.addEventListener('click', function(event){

    if(event.target.tagName.toLowerCase() === 'li'){

        addToInput(event.target)
    }
})


思考
之前做过一个前端搜索的,那个还嵌套了两层,所以这个就驾轻熟路啦。

如果数据量比较大的话,可以用一些搜索的算法,比如二分或者基类等。也可以给数组先排个序。

如果对字符串是模糊搜索的话,可以用kmp算法。

这里想的比较简单。就是看首字母。startsWith() 好像是es6 的功能吧。

当然,如果数据量更大的话,通常就交给后端了,前端会调用接口来返回结果。
————————————————
版权声明:本文为CSDN博主「十方魔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/github_36487770/article/details/80084512

4.函数的长度length

今天在看函数式编程时,发现了一段有意思的代码,如下:

function a(x,y){}
a.length // 2
 
function b(x,y=2,z){}
b.length // 1
 
function c(x,...args){}
c.length //1


运行了一下,结果没错,知道length属性指的是形参的个数,但是不明白后两种函数为啥length的值为1。找了资料,弥补了这块小知识点的空缺,定义如下:

length 是JS函数对象的一个属性值,该值是指 “该函数有多少个必须要传入的参数”,即形参的个数
形参的数量不包括剩余参数个数,仅包括 “第一个具有默认值之前的参数个数”
看到整个定义后,就明白了为啥后两种的值为 1 了。

在没有默认值时,fn.length指的是形参的个数,如果有参数有默认值,那么就取第一个具有默认值之前的参数的个数。

多写几个例子看看?

function d(x,y=1,z,w){}
d.length //1
 
function e(x,y,z,w=3){}
e.length //3
 
function f(){}
f.length //0
 
function g(a=1,b=1,c=1){}
g.length //0
除了这个之外,延伸了解一下,函数的实参个数应该怎么获取?

arguments.length //在函数内部使用,表示实际传入的参数个数,在运行时计算,和形参个数无关
再来几个例子:

function a(x,y,z){
   console.log(arguments.length); // 3
}(1,2,3)
 
function b(x,y=2){
    console.log(arguments.length) // 3
}(1,2,3)
 
 
function c(x,y=2){
    console.log(arguments.length) // 1
}(1)
 
function d(x,...args){
    console.log(arguments.length) // 2
}(1,2)
 
function e(){
    console.log(arguments.length) // 4
}(1,2,3,4)


JS中形参和实参的长度到这应该已经比较清楚啦,撒花。
————————————————
版权声明:本文为CSDN博主「Lin_Dan_Dan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010176097/article/details/97257375

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值