목차
- 머리말 + 질문
- 1. 통화 및 적용
- 3. 통화 시뮬레이션
- 5.
- 머리말 + 생각하는 질문
인턴십을 찾을 때 항상 JS에 익숙한 이력서에 this, call, Apply 등의 문장을 추가했던 기억이 나네요...
(무료 학습 추천:
javascript 비디오 튜토리얼)저는 이력서를 제출할 때마다 다음 단계를 거치게 됩니다
면접 전에 Du Niang에게 물어보세요 - 어떤 유형인지 포인팅은 ~, 호출, 적용으로 구분할 수 있는데 차이점이 무엇인가요? 자신감이 0%에서 50%로 치솟았네요 면접때 면접관이 몇문제를 닥치는 대로 던지는데, 확고한 답변을 해줄 수 있는데 결과는 늘 불만족스럽네요...- 면접이 끝난 후, 부끄럽습니다. 이력서에서 이 항목을 삭제하세요. 그리고 나중에 이력서 제출할 때 이 항목을 또 추가했는데...
다음 질문은 제가 인터넷에서 검색한 인기 질문들입니다. 전문가들이 쉽게 답변해 주신다면. 명확한 아이디어라면 엄지손가락을 치켜세우는 것이 좋을 것입니다(결국 뇌 세포를 많이 소모하기 때문입니다). 댓글로 몇 가지 조언을 해주시면 더 좋을 것 같습니다! ! !
Javascript에서 [ ]
함수를 실행하면 새 함수가 호출된 함수와 동일한 함수 본문을 갖습니다. 호출되면 이 값은 첫 번째 매개변수를 가리킵니다.
- Q&A:
【 】
函数会创建一个新函数,新函数与被调函数具有相同的函数体,当目标函数被调用时 this 值指向第一个参数。
问答题:
- 请你谈一下改变函数内部this指针的指向函数有哪几种,他们的区别是什么?
- this的指向可以分为哪几种?
代码分析题:
var name = 'window'var person1 = { name: 'person1', show1: function () { console.log(this.name) }, show2: () => console.log(this.name), show3: function () { return function () { console.log(this.name) } }, show4: function () { return () => console.log(this.name) }}var person2 = { name: 'person2' }person1.show1()person1.show1.call(person2)person1.show2()person1.show2.call(person2)person1.show3()()person1.show3().call(person2)person1.show3.call(person2)()person1.show4()()person1.show4().call(person2)person1.show4.call(person2)()
一、this的指向
百度、谷歌上输入“this的指向”关键字,大几千条文章肯定是有的,总不至于为了全方面、无死角的掌握它就要将所有的文章都看一遍吧?所以不如梳理出一个稳固的框架,顺着我们的思路来填充它。
思维导图
本节精华:
- this 总是(非严格模式下)指向一个对象,而具体指向哪个对象是在运行时基于函数的
执行环境
动态绑定的,而非函数被声明时的环境; - 除了不常用的with和eval的情况,具体到实际应用中,this指向大概可以分为四种:
- 作为对象的方法调用;
- 作为普通函数调用;
- 构造器调用;
- call 或 apply调用;
- 箭头函数中,this指向函数上层作用域的this;
-
构造器和普通函数的区别在于
被调用的方式
; - A,call(B) => 可以理解成在B的作用域内调用了A方法;
分析
1、作为对象的方法调用
当函数作为对象的方法被调用时,this指向该对象
var obj = { a: 'yuguang', getName: function(){ console.log(this === obj); console.log(this.a); }};obj.getName(); // true yuguang
2、作为普通函数调用
当函数不作为对象的属性被调用,而是以普通函数的方式,this总是指向全局对象(在浏览器中,通常是Window对象)
window.name = 'yuguang';var getName = function(){ console.log(this.name);};getName(); // yuguang
或者下面这段迷惑性的代码:
window.name = '老王'var obj = { name: 'yuguang', getName: function(){ console.log(this.name); }};var getNew = obj.getName;getNew(); // 老王
而在ES5的严格模式下,this被规定为不会指向全局对象,而是undefined
3、构造器调用
除了一些内置函数,大部分Js中的函数都可以成为构造器,它们与普通函数没什么不同
构造器和普通函数的区别在于被调用的方式
함수 내에서 this 포인터를 변경하는 포인터 함수의 종류와 차이점에 대해 이야기해주세요.
이것은 어떤 방향으로 나눌 수 있나요?
코드 분석 질문:
var MyClass = function(){ this.name = 'yuguang';}var obj = new MyClass();obj.name; // yuguang
1. 요점은
바이두와 구글에 "point of this"라는 키워드를 입력하세요. 수천 개의 기사가 있을 텐데 모든 것을 포함하지는 않습니다. , 사각지대 없이 마스터하려면 기사를 다 읽어야겠죠? 그러니 탄탄한 틀을 정리하고 우리의 생각대로 채워가는 것이 좋습니다. 마인드맵🎜🎜
실행 환경
을 기반으로 동적으로 바인딩됩니다. 선언된 환경 🎜🎜일반적이지 않은 with 및 eval 상황을 제외하고 실제 응용 프로그램에서 이 포인터는 대략 4가지 유형으로 나눌 수 있습니다. 🎜🎜객체의 메서드 호출 🎜🎜일반적인 함수 호출; 🎜🎜 생성자 호출; 🎜🎜호출 또는 적용 🎜🎜화살표 함수에서 이는 함수의 상위 범위를 가리킵니다. 🎜🎜🎜🎜🎜constructor🎜와 🎜일반 함수🎜의 차이점은 다음과 같습니다. 가 호출됩니다;🎜🎜A,call(B) => B의 범위 내에서 메소드 A가 호출되는 것으로 이해할 수 있습니다.🎜🎜🎜Analytic🎜🎜🎜1. 🎜🎜함수가 객체일 때 메소드가 호출될 때 <code>이것은 객체를 가리킨다
🎜var MyClass = function () { this.name = 1; return { name: 2 }}var myClass = new MyClass(); console.log('myClass:', myClass); // { name: 2}🎜🎜2. 일반 함수로 호출됩니다🎜🎜🎜함수가 의 속성으로 호출되지 않을 때 객체이지만 일반 함수에서는 항상 전역 객체(브라우저에서는 일반적으로 Window 객체)를 가리킵니다. 🎜
var obj1 = { name: 1, getName: function (num = '') { return this.name + num; }};var obj2 = { name: 2,};// 可以理解成在 obj2的作用域下调用了 obj1.getName()函数console.log(obj1.getName()); // 1console.log(obj1.getName.call(obj2, 2)); // 2 + 2 = 4console.log(obj1.getName.apply(obj2, [2])); // 2 + 2 = 4🎜 또는 다음과 같은 혼란스러운 코드: 🎜
this.val = 2;var obj = { val: 1, getVal: () => { console.log(this.val); }}obj.getVal(); // 2🎜 ES5의 엄격 모드에서는 그렇지 않다고 규정되어 있습니다. 전역 객체를 가리키지만 undefine🎜🎜🎜3. 생성자 호출🎜🎜🎜일부 내장 함수를 제외하면 Js의 대부분 함수는 생성자가 될 수 있습니다. 🎜🎜🎜constructors🎜and🎜ordinary 함수 🎜의 차이점은
호출
방식에 있습니다. 🎜 new 연산자가 함수를 호출하면 항상 개체를 반환하며 이는 일반적으로 이 개체를 가리킵니다 🎜 var obj = { name: '1', getName: function (params) { console.log(this.name) }};obj.getName();var getName2 = obj.getName;getName2();🎜 그러나 함수가 명시적으로 객체 객체를 반환하는 경우 이 작업의 결과는 결국 이 객체를 반환하게 됩니다. 🎜
var getDomById = function (id) { return document.getElementById(id);};getDomById('p1') //dom节点🎜생성자가 명시적으로 데이터를 반환하지 않거나 객체 유형이 아닌 데이터를 반환하는 한 위의 문제는 발생하지 않습니다. 🎜🎜🎜4. 호출 또는 적용 호출🎜🎜🎜일반 함수 호출과 비교하여 호출 및 적용은 함수의 this를 동적으로 변경할 수 있습니다🎜
var getDomById = document.getElementByIdgetDomById('p1') // Uncaught TypeError: Illegal invocation(非法调用)🎜🎜5. 화살표 함수는 자체 this를 생성하지 않습니다. 자체 범위 체인의 상위 수준에서만 이를 상속합니다. 🎜
因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同:
this.val = 2;var obj = { val: 1, getVal: () => { console.log(this.val); }}obj.getVal(); // 2
常见的坑
就像标题一样,有的时候this
会指向undefined
情况一
var obj = { name: '1', getName: function (params) { console.log(this.name) }};obj.getName();var getName2 = obj.getName;getName2();
这个时候,getName2()
作为普通函数被调用时,this指向全局对象——window。
情况二
当我们希望自己封装Dom方法,来精简代码时:
var getDomById = function (id) { return document.getElementById(id);};getDomById('p1') //dom节点
那么我们看看这么写行不行?
var getDomById = document.getElementByIdgetDomById('p1') // Uncaught TypeError: Illegal invocation(非法调用)
这是因为:
- 当我们去调用
document
对象的方法时,方法内的this指向document
。 - 当我们用
getId
应用document
内的方法,再以普通函数的方式调用,函数内容的this
就指向了全局对象。
利用call和apply修正情况二
document.getElementById = (function (func) { return function(){ return func.call(document, ...arguments) }})(document.getElementById) // 利用立即执行函数将document保存在作用域中
二、call和apply
不要因为它的“强大”而对它产生抗拒,了解并熟悉它是我们必须要做的,共勉!
思维导图
1.call和apply区别
先来看区别,是因为它们几乎没有区别,下文代码实例call和apply都可以轻易的切换。
当它们被设计出来时要做到的事情一摸一样,唯一的区别就在于传参的格式不一样
- apply接受两个参数
- 第一个参数指定了函数体内this对象的指向
- 第二个参数为一个带下标的参数集合(可以是数组或者类数组)
- call接受的参数不固定
- 第一个参数指定了函数体内this对象的指向
- 第二个参数及以后为函数调用的参数
因为在所有(非箭头)函数中都可以通过arguments
对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,它本身就是一个类数组,我们apply在实际使用中更常见一些。
call是包装在apply上面的语法糖,如果我们明确的知道参数数量,并且希望展示它们,可以使用call。
当使用call或者apply的时候,如果我们传入的第一个参数为null,函数体内的this会默认指向宿主对象,在浏览器中则是window
。
借用其他对象的方法
我们可以直接传null来代替任意对象
Math.max.apply(null, [1, 2, 3, 4, 5])
2.call和apply能做什么?
使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数——来时MDN
- 调用构造函数来
实现继承
; - 调用函数并且指定上下文的
this
; - 调用函数并且不指定第一个参数;
1.调用构造函数来实现继承
通过“借用”的方式来达到继承的效果:
function Product(name, price) { this.name = name; this.price = price;}function Food(name, price) { Product.call(this, name, price); // this.category = food;}var hotDog = new Food('hotDog', 20);
2.调用函数并且指定上下文的 this
此时this被指向了obj
function showName() { console.log(this.id + ':' + this.name);};var obj = { id: 1, name: 'yuguang'};showName.call(obj)
3.使用call单纯的调用某个函数
Math.max.apply(null, [1,2,3,10,4,5]); // 10
三、模拟实现一个call
先来看一下call帮我们需要做什么?
var foo = { value: 1};function show() { console.log(this.value);};show.call(foo); //1
就像解方程,要在已知条件中寻找突破哦口:
-
call
使得this的指向变了,指向了foo; -
show
函数被执行了; - 传入的参数应为
this
+ 参数列表;
第一版代码
上面提到的3点,仅仅完成了一点,且传入的参数
var foo = { value: 1};function show() { console.log(this.value);};Function.prototype.setCall = function (obj) { console.log(this); // 此时this指向show obj.func = this; // 将函数变成对象的内部属性 obj.func(obj.value); // 指定函数 delete obj.func // 删除函数,当做什么都没发生~}show.setCall(foo);
第二版代码
为了解决参数的问题,我们要能获取到参数,并且正确的传入:
var foo = { value: 1};function show(a, b) { console.log(this.value); console.log(a + b);};Function.prototype.setCall = function (obj) { obj.fn = this; // 将函数变成对象的内部属性 var args = []; for(let i = 1; i <p>此时,我们就可以做到,传入多个参数的情况下使用call了,但是如果你仅想用某个方法呢?</p><p><strong>第三版代码</strong></p><pre class="brush:php;toolbar:false">Function.prototype.setCall = function (obj) { var obj = obj || window; obj.fn = this; var args = []; for(var i = 1, len = arguments.length; i <p><strong>四、bind</strong></p><blockquote><p>bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用 —— MDN</p></blockquote><p>提到了<strong>call</strong>和<strong>apply</strong>,就绕不开<strong>bind</strong>。我们试着来模拟一个bind方法,以便加深我们的认识:</p><pre class="brush:php;toolbar:false">Function.prototype.bind = function (obj) { var _this = this; // 保存调用bind的函数 var obj = obj || window; // 确定被指向的this,如果obj为空,执行作用域的this就需要顶上喽 return function(){ return _this.apply(obj, arguments); // 修正this的指向 }};var obj = { name: 1, getName: function(){ console.log(this.name) }};var func = function(){ console.log(this.name);}.bind(obj);func(); // 1
这样看上去,返回一个原函数的拷贝,并拥有指定的 this 值,还是挺靠谱的哦~
写在最后
JavaScript 내부 기술의 기본 부분 중 첫 번째 부분입니다. 요약하면 이 시리즈는 Xian Yu에게 큰 격려와 영감을 얻었습니다. 이 시리즈에는 약 15개의 기사가 있으며, 모두 우리가 가장 자주 인터뷰하지만 직장에서는 종종 무시됩니다. .
관련 무료 학습 권장사항: javascript(동영상)
위 내용은 이 포인터에 대한 자세한 설명을 통해 이를 이해하고 전화하고 적용할 수 있는 기사를 하나의 문서로 제공합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

웹 개발에서 JavaScript의 주요 용도에는 클라이언트 상호 작용, 양식 검증 및 비동기 통신이 포함됩니다. 1) DOM 운영을 통한 동적 컨텐츠 업데이트 및 사용자 상호 작용; 2) 사용자가 사용자 경험을 향상시키기 위해 데이터를 제출하기 전에 클라이언트 확인이 수행됩니다. 3) 서버와의 진실한 통신은 Ajax 기술을 통해 달성됩니다.

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

Python과 JavaScript는 커뮤니티, 라이브러리 및 리소스 측면에서 고유 한 장점과 단점이 있습니다. 1) Python 커뮤니티는 친절하고 초보자에게 적합하지만 프론트 엔드 개발 리소스는 JavaScript만큼 풍부하지 않습니다. 2) Python은 데이터 과학 및 기계 학습 라이브러리에서 강력하며 JavaScript는 프론트 엔드 개발 라이브러리 및 프레임 워크에서 더 좋습니다. 3) 둘 다 풍부한 학습 리소스를 가지고 있지만 Python은 공식 문서로 시작하는 데 적합하지만 JavaScript는 MDNWebDocs에서 더 좋습니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.
